@ -19,19 +19,32 @@
let MbState = { } ;
let MbState = { } ;
let MbApiTransformer ;
let MbApiTransformer ;
function MbStorage ( key , value ) {
base = 'org.eu.octt.MBViewer/v1' ;
data = ( JSON . parse ( localStorage . getItem ( base ) ) || { } ) ;
if ( value === undefined ) {
return data [ key ] ;
}
data [ key ] = value ;
return localStorage . setItem ( base , JSON . stringify ( data ) ) ;
}
function ArgsRewrite ( props = { } , navigate = true ) {
function ArgsRewrite ( props = { } , navigate = true ) {
for ( const key in props ) {
for ( const key in props ) {
const value = props [ key ] ;
const value = props [ key ] ;
value ? ( MbState . args [ key ] = value ) : ( delete MbState . args [ key ] ) ;
value ? ( MbState . args [ key ] = value ) : ( delete MbState . args [ key ] ) ;
}
}
let hash = '/' ;
let hash = ' ';
for ( const arg in MbState . args ) {
for ( const arg in MbState . args ) {
hash += ` ${ arg } = ${ MbState . args [ arg ] } | ` ;
hash += ` ${ arg } = ${ MbState . args [ arg ] } | ` ;
}
}
if ( hash ) {
hash = ` / ${ hash } ` ;
}
if ( navigate ) {
if ( navigate ) {
location . hash = hash ;
location . hash = hash ;
}
}
return hash
return hash ;
}
}
const SureArray = ( obj ) => ( Array . isArray ( obj ) ? obj : [ obj ] ) ;
const SureArray = ( obj ) => ( Array . isArray ( obj ) ? obj : [ obj ] ) ;
@ -74,8 +87,9 @@ function MakeSiteRestUrl (path='') {
return ` ${ siteUrl } /wp-content/uploads/ ${ siteUrl . split ( '.' ) . slice ( 0 , 1 ) [ 0 ] . split ( '//' ) [ 1 ] } /scripts/stuff.php?&Thing=SiteWpJsonCors&AccessToken=9ab6e20c& $ Query= ${ encodeURIComponent ( path ) } ` ;
return ` ${ siteUrl } /wp-content/uploads/ ${ siteUrl . split ( '.' ) . slice ( 0 , 1 ) [ 0 ] . split ( '//' ) [ 1 ] } /scripts/stuff.php?&Thing=SiteWpJsonCors&AccessToken=9ab6e20c& $ Query= ${ encodeURIComponent ( path ) } ` ;
} else {
} else {
if ( [ "atom" , "rss" , "wordpress.org" ] . includes ( MbState . platform ) ) {
if ( [ "atom" , "rss" , "wordpress.org" ] . includes ( MbState . platform ) ) {
const proxies = [ "corsproxy.io" , "corsproxy.org" ] ;
const proxies = [ "hlb0.octt.eu.org/cors-main.php/" , "corsproxy.io/?" , /*"corsproxy.org/?"*/ ] ;
return ` https:// ${ proxies [ ~ ~ ( Math . random ( ) * proxies . length ) ] } /? ${ siteUrl } / ${ MbState . platform === 'wordpress.org' ? ` wp-json/ ${ path } ` : '' } ` ;
const proxy = proxies [ ~ ~ ( Math . random ( ) * proxies . length ) ] ;
return ` https:// ${ proxy } ${ siteUrl } ${ MbState . platform === 'wordpress.org' ? ` /wp-json/ ${ path } ` : '' } ` ;
} else if ( MbState . platform === 'wordpress.com' ) {
} else if ( MbState . platform === 'wordpress.com' ) {
return ` https://public-api.wordpress.com/rest/v1.1/sites/ ${ GetDomainFromUrl ( siteUrl ) } / ${ path } ` ;
return ` https://public-api.wordpress.com/rest/v1.1/sites/ ${ GetDomainFromUrl ( siteUrl ) } / ${ path } ` ;
} else if ( MbState . platform === 'mastodon' ) {
} else if ( MbState . platform === 'mastodon' ) {
@ -117,7 +131,7 @@ function MakeApiEndpoint (type, options={}) {
return query ;
return query ;
}
}
function MakeAcroName ( name ) {
function MakeAcroName ( name ) {
let acro = '' ;
let acro = '' ;
for ( const word of name . split ( ' ' ) . slice ( 0 , 3 ) ) {
for ( const word of name . split ( ' ' ) . slice ( 0 , 3 ) ) {
acro += word [ 0 ] . toUpperCase ( ) ;
acro += word [ 0 ] . toUpperCase ( ) ;
@ -125,10 +139,40 @@ function MakeAcroName(name) {
return acro ;
return acro ;
}
}
async function MbViewerInit ( ) {
function UpdateChatOpenTime ( queryUrl ) {
if ( ! location . hash ) {
const chats = MbStorage ( 'chats' ) ;
location . hash = '/' ;
for ( const chatIndex in chats ) {
if ( chats [ chatIndex ] . queryUrl == queryUrl ) {
chats [ chatIndex ] . openTime = Date . now ( ) ;
MbStorage ( 'chats' , chats ) ;
break ;
}
}
}
}
function CheckChatFavorite ( siteUrl ) {
return MbStorage ( 'chats' ) . some ( ( chat ) => ( chat . siteUrl === siteUrl ) ) ;
}
function ToggleChatFavorite ( siteUrl ) {
const chats = MbStorage ( 'chats' ) ;
const present = CheckChatFavorite ( siteUrl ) ;
if ( ! present ) {
chats . push ( { name : MbState . siteData . name , iconUrl : MbState . siteData . iconUrl , siteUrl , queryUrl : location . hash , openTime : Date . now ( ) } ) ;
MbStorage ( 'chats' , chats ) ;
} else {
for ( const chatIndex in chats ) {
if ( chats [ chatIndex ] . siteUrl === siteUrl ) {
chats . splice ( chatIndex , 1 ) ;
MbStorage ( 'chats' , chats ) ;
break ;
}
}
}
$ ( 'button[name="ToggleChatFavorite"]' ) . html ( ` ${ present ? '➕ ️ Add to' : '❌️ Remove from' } favorites ⭐️ ` ) ;
}
async function MbViewerInit ( ) {
if ( ! MbApiTransformer ) {
if ( ! MbApiTransformer ) {
MbApiTransformer = Trasformapi ( MbViewerTrasformapiSchema ) . TransformForInput ;
MbApiTransformer = Trasformapi ( MbViewerTrasformapiSchema ) . TransformForInput ;
}
}
@ -159,11 +203,7 @@ async function MbViewerInit () {
if ( ! urlLow . startsWith ( 'http://' ) && ! urlLow . startsWith ( 'https://' ) ) {
if ( ! urlLow . startsWith ( 'http://' ) && ! urlLow . startsWith ( 'https://' ) ) {
url = ` https:// ${ url } ` ;
url = ` https:// ${ url } ` ;
}
}
if ( [ "t.me" , "telegram.me" ] . includes ( url . toLowerCase ( ) . split ( '://' ) [ 1 ] . split ( '/' ) [ 0 ] ) ) {
location = url ;
} else {
ArgsRewrite ( { siteurl : url } ) ;
ArgsRewrite ( { siteurl : url } ) ;
}
event . preventDefault ( ) ;
event . preventDefault ( ) ;
} ;
} ;
$ ( 'a.tgme_header_link' ) [ 0 ] . onclick = function ( ) {
$ ( 'a.tgme_header_link' ) [ 0 ] . onclick = function ( ) {
@ -196,8 +236,40 @@ async function MbViewerInit () {
MbState . args [ argTokens [ 0 ] . toLowerCase ( ) ] = ( valueItems . length > 1 ? valueItems : valueItems [ 0 ] ) ;
MbState . args [ argTokens [ 0 ] . toLowerCase ( ) ] = ( valueItems . length > 1 ? valueItems : valueItems [ 0 ] ) ;
}
}
}
}
if ( ! Object . keys ( MbState . args ) . length ) {
$ ( 'a[name="goBack"]' ) [ 0 ] . hidden = true ;
$ ( '.tgme_header_title' ) . html ( MbState . siteData . name ) ;
$ ( '.tgme_header_right_column' ) [ 0 ] . hidden = true ;
$ ( 'div.ChatList > div.ChatAdds' ) [ 0 ] . innerHTML = '' ;
$ ( 'div.ChatList' ) [ 0 ] . hidden = false ;
for ( const chat of [ ... MbStorage ( 'chats' ) ] . sort ( ( a , b ) => ( b . openTime || 0 ) - ( a . openTime || 0 ) ) ) {
if ( ! chat . queryUrl ) {
continue ;
}
$ ( 'div.ChatList > div.ChatAdds' ) [ 0 ] . innerHTML += ` <div class="ChatButton">
< a href = "${chat.queryUrl}" onclick = "UpdateChatOpenTime('${chat.queryUrl}')" >
< i class = "tgme_widget_message_user_photo" data - content = "${!chat.iconUrl ? MakeAcroName(chat.name) : ''}" >
< img src = "${chat.iconUrl || ''}" / >
< / i >
< span > $ { chat . name } < / s p a n >
< / a >
< / d i v > ` ;
}
return
}
$ ( 'div.ChatList' ) [ 0 ] . hidden = true ;
$ ( '.tgme_header_right_column' ) [ 0 ] . hidden = false ;
MbState . siteUrl = MbState . args . siteurl ;
MbState . siteUrl = MbState . args . siteurl ;
MbState . platform = /*SureArray(*/ MbState . args . platform /*)*/ ;
MbState . platform = /*SureArray(*/ MbState . args . platform /*)*/ ;
if ( ! MbState . platform && MbState . siteUrl ) {
if ( [ "t.me" , "telegram.me" ] . includes ( GetDomainFromUrl ( MbState . siteUrl ) . toLowerCase ( ) ) ) {
MbState . siteUrl = ` https://rsshub.app/telegram/channel/ ${ MbState . siteUrl . split ( '//' ) [ 1 ] . split ( '/' ) [ 1 ] } ` ;
MbState . platform = 'rss' ;
}
if ( MbState . siteUrl . toLowerCase ( ) . endsWith ( '.rss' ) ) {
MbState . platform = 'rss' ;
}
}
MbState . postId = MbState . args . postid ;
MbState . postId = MbState . args . postid ;
//MbState.postSlug = MbState.args.postslug;
//MbState.postSlug = MbState.args.postslug;
RefreshIncludeStyle ( ) ;
RefreshIncludeStyle ( ) ;
@ -318,9 +390,7 @@ async function MbViewerInit () {
$ ( 'form.tgme_header_search_form' ) [ 0 ] . onsubmit = null ;
$ ( 'form.tgme_header_search_form' ) [ 0 ] . onsubmit = null ;
$ ( '.tgme_channel_info_header_username' ) . html ( ` <a href=" ${ siteLink } "> ${ GetDomainFromUrl ( siteLink ) . toLowerCase ( ) } </a> ` ) ;
$ ( '.tgme_channel_info_header_username' ) . html ( ` <a href=" ${ siteLink } "> ${ GetDomainFromUrl ( siteLink ) . toLowerCase ( ) } </a> ` ) ;
}
}
if ( MbState . siteUrl || MbState . dataInject ) {
$ ( 'a[name="goBack"]' ) [ 0 ] . hidden = false ;
$ ( 'a[name="goBack"]' ) [ 0 ] . hidden = false ;
}
if ( [ "atom" , "rss" ] . includes ( MbState . platform ) ) {
if ( [ "atom" , "rss" ] . includes ( MbState . platform ) ) {
$ ( 'section.tgme_channel_history.js-message_history' ) . html ( MakeMoreWrapperHtml ( ) ) ;
$ ( 'section.tgme_channel_history.js-message_history' ) . html ( MakeMoreWrapperHtml ( ) ) ;
TWeb . loadMore ( $ ( '.js-messages_more_wrap > a' ) , MbState . siteData ) ;
TWeb . loadMore ( $ ( '.js-messages_more_wrap > a' ) , MbState . siteData ) ;
@ -333,13 +403,12 @@ async function MbViewerInit () {
MbState . siteData . iconUrl = ` ${ MbState . siteUrl } ${ MbState . siteData . iconUrl } ` ;
MbState . siteData . iconUrl = ` ${ MbState . siteUrl } ${ MbState . siteData . iconUrl } ` ;
}
}
if ( ! MbState . siteUrl && ! MbState . dataInject ) {
if ( ! MbState . siteUrl && ! MbState . dataInject ) {
$ ( 'a[name="goBack"]' ) [ 0 ] . hidden = true ;
$ ( 'section.tgme_channel_history.js-message_history' ) . html ( MakeMoreWrapperHtml ( ) ) ;
$ ( 'section.tgme_channel_history.js-message_history' ) . html ( MakeMoreWrapperHtml ( ) ) ;
TWeb . loadMore ( $ ( '.js-messages_more_wrap > a' ) , [ { content : ` <p>
TWeb . loadMore ( $ ( '.js-messages_more_wrap > a' ) , [ { content : ` <p>
Here I am , doing another strange thing of mine .
Here I am , doing another strange thing of mine .
This is my personal experiment to make an MB - style frontend for sources that are by default not really friendly to that concept .
This is my personal experiment to make an MB - style frontend for sources that are by default not really friendly to that concept .
Since this first day , we will start with just WordPress , and we ' ll see what comes from that .
Since this first day , we will start with just WordPress , and we ' ll see what comes from that .
See < a href = "https://octospacc.altervista.org/2024/01/13/wordpress-che-non-e/" > https: // octospacc.altervista.org/2024/01/13/wordpress-che-non-e/</a>.
See < a href = "https://octospacc.altervista.org/2024/01/13/wordpress-che-non-e/" > octospacc . altervista . org / 2024 / 01 / 13 / wordpress - che - non - e / < / a > .
< / p > ` , t i m e : ' 2 0 2 4 - 0 1 - 1 3 T 2 1 : 0 0 ' } , { c o n t e n t : ` < p >
< / p > ` , t i m e : ' 2 0 2 4 - 0 1 - 1 3 T 2 1 : 0 0 ' } , { c o n t e n t : ` < p >
After fixing a few post - release issues driving me insane ( scrolling cough cough ) , here are some new improvements :
After fixing a few post - release issues driving me insane ( scrolling cough cough ) , here are some new improvements :
< br / > * Handling of posts without date is just a bit nicer .
< br / > * Handling of posts without date is just a bit nicer .
@ -386,7 +455,7 @@ async function MbViewerInit () {
< br / > * Read Telegram ' s JSON chat exports ( experimental , very slow and resource - heavy )
< br / > * Read Telegram ' s JSON chat exports ( experimental , very slow and resource - heavy )
< br / >
< br / >
Regarding Trasformapi , I transformed some of my development tears into words , read here if you ' re curious :
Regarding Trasformapi , I transformed some of my development tears into words , read here if you ' re curious :
< a href = "https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/" > https: // octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/</a>.
< a href = "https://octospacc.altervista.org/2024/01/25/mbviewer-per-distrarci/" > octospacc . altervista . org / 2024 / 01 / 25 / mbviewer - per - distrarci / < / a > .
< / p > ` , t i m e : ' 2 0 2 4 - 0 1 - 2 5 T 0 1 : 0 0 ' } , { c o n t e n t : ` < p >
< / p > ` , t i m e : ' 2 0 2 4 - 0 1 - 2 5 T 0 1 : 0 0 ' } , { c o n t e n t : ` < p >
Some small things :
Some small things :
< br / > * Fixed RSS feeds parsing on Firefox ( mentioned in the post linked above ) , by fixing a bug in Trasformapi
< br / > * Fixed RSS feeds parsing on Firefox ( mentioned in the post linked above ) , by fixing a bug in Trasformapi
@ -396,12 +465,19 @@ async function MbViewerInit () {
New changes :
New changes :
< br / > * Support including user - defined JS scripts from URL ( < code > data : < / c o d e > s u p p o r t e d ) v i a t h e < c o d e > i n c l u d e S c r i p t < / c o d e > a r g u m e n t . A s c r i p t m u s t e x p o s e a < c o d e > M b V i e w e r F u n c t i o n ( d a t a ) < / c o d e > f u n c t i o n t o b e i n v o k e d b y t h e m a i n a p p l i c a t i o n t o d o u s e f u l o p e r a t i o n s , a n d t h e n r e t u r n d a t a b y c a l l i n g t h e < c o d e > M b V i e w e r R e t u r n ( d a t a ) < / c o d e > A P I f u n c t i o n .
< br / > * Support including user - defined JS scripts from URL ( < code > data : < / c o d e > s u p p o r t e d ) v i a t h e < c o d e > i n c l u d e S c r i p t < / c o d e > a r g u m e n t . A s c r i p t m u s t e x p o s e a < c o d e > M b V i e w e r F u n c t i o n ( d a t a ) < / c o d e > f u n c t i o n t o b e i n v o k e d b y t h e m a i n a p p l i c a t i o n t o d o u s e f u l o p e r a t i o n s , a n d t h e n r e t u r n d a t a b y c a l l i n g t h e < c o d e > M b V i e w e r R e t u r n ( d a t a ) < / c o d e > A P I f u n c t i o n .
< br / >
< br / >
... I will probably need to write actual documentation about this , but for sure I will post about this on < a href = "https://octospacc.altervista.org/?p=1416" > https: // octospacc.altervista.org/?p=1416</a>.
... I will probably need to write actual documentation about this , but for sure I will post about this on < a href = "https://octospacc.altervista.org/?p=1416" > octospacc . altervista . org / ? p = 1416 < / a > .
< / p > ` , t i m e : ' 2 0 2 4 - 0 2 - 0 1 T 0 0 : 0 0 ' } , { c o n t e n t : ` < p >
< / p > ` , t i m e : ' 2 0 2 4 - 0 2 - 0 1 T 0 0 : 0 0 ' } , { c o n t e n t : ` < p >
Updates :
Updates :
< br / > * Include special CSS for optimized PDF / paper printing
< br / > * Include special CSS for optimized PDF / paper printing
< / p > ` , t i m e : ' 2 0 2 4 - 0 2 - 0 5 T 1 1 : 0 0 ' } , { c o n t e n t : ` < p >
< / p > ` , t i m e : ' 2 0 2 4 - 0 2 - 0 5 T 1 1 : 0 0 ' } , { c o n t e n t : ` < p > < ! - -
Copyright notice : MBViewer uses code borrowed from < a href = "https://t.me" > t . me < / a > ,
++ -- > * Added a main sources list , new ones can be added via a button in their menu after being open by URL
< br / > * Made the printable CSS a bit nicer with borders , margins , and properly - sized images
< br / > * Updated CORS proxies
< br / > * Now handling Telegram URLs via < a href = "https://rsshub.app" > RSSHub . app < / a >
< br / > * Probably fixed an issue with < code > location . hash < / c o d e > o v e r r i d i n g t h a t m a d e g o i n g b a c k t o a n o t h e r s i t e f r o m t h e a p p i m p o s s i b l e
< br / > Devlog : < a href = "https://octospacc.altervista.org/?p=7098" > octospacc . altervista . org / ? p = 7098 < / a > .
< / p > ` , t i m e : ' 2 0 2 4 - 0 7 - 0 1 T 2 0 : 0 0 ' } , { c o n t e n t : ` < p >
Copyright notice : MBViewer uses code borrowed from < a href = "https://t.me" > https : //t.me</a>,
specially modified to handle customized data visualizations in an MB - style .
specially modified to handle customized data visualizations in an MB - style .
< br / >
< br / >
This webapp is not affiliated with Telegram ( Telegram FZ LLC , Telegram Messenger Inc . ) , and
This webapp is not affiliated with Telegram ( Telegram FZ LLC , Telegram Messenger Inc . ) , and
@ -411,7 +487,7 @@ async function MbViewerInit () {
document . title = ` ${ MbState . siteData . name } — 👁️🗨️️ MBViewer ` ;
document . title = ` ${ MbState . siteData . name } — 👁️🗨️️ MBViewer ` ;
$ ( '.tgme_page_photo_image' ) . attr ( 'data-content' , MbState . siteData . acroName ) ;
$ ( '.tgme_page_photo_image' ) . attr ( 'data-content' , MbState . siteData . acroName ) ;
$ ( '.tgme_header_title, .tgme_channel_info_header_title' ) . html ( MbState . siteData . name ) ;
$ ( '.tgme_header_title, .tgme_channel_info_header_title' ) . html ( MbState . siteData . name ) ;
$ ( '.tgme_channel_info_description' ) . html ( MbState . siteData . description ) ;
$ ( '.tgme_channel_info_description' ) . html ( ( MbState . siteUrl ? ` <div><p><button name="ToggleChatFavorite" onclick="ToggleChatFavorite(' ${ MbState . siteUrl } ')"> ${ ! CheckChatFavorite ( MbState . siteUrl ) ? '➕ ️ Add to' : '❌️ Remove from' } favorites ⭐️</button></p></div> ` : '' ) + MbState . siteData . description ) ;
if ( MbState . siteData . iconUrl ) {
if ( MbState . siteData . iconUrl ) {
$ ( '.tgme_page_photo_image' ) . html ( ` <img src=" ${ MbState . siteData . iconUrl } "/> ` ) ;
$ ( '.tgme_page_photo_image' ) . html ( ` <img src=" ${ MbState . siteData . iconUrl } "/> ` ) ;
} else {
} else {
@ -652,9 +728,16 @@ function ResizeLayouts () {
}
}
$ ( 'a[name="goBack"]' ) [ 0 ] . onclick = function ( ) {
$ ( 'a[name="goBack"]' ) [ 0 ] . onclick = function ( ) {
ArgsRewrite ( { dataurl : null , siteurl : null , postid : null , platform : null , includestyle : null , includescript : null /*postslug: null*/ } ) ;
//ArgsRewrite({ dataurl: null, siteurl: null, postid: null, platform: null, includestyle: null, includescript: null /*postslug: null*/ });
location . hash = '' ;
} ;
} ;
if ( ! MbStorage ( 'chats' ) ) {
const octospacc = { name : "fritto misto di octospacc <small>(Consigliato)</small>" , siteUrl : "https://octospacc.altervista.org" , iconUrl : "https://octospacc.altervista.org/wp-content/uploads/2024/05/fried-shrimp_1f364.png" } ;
octospacc . queryUrl = ` #/siteUrl= ${ octospacc . siteUrl } ` ;
MbStorage ( 'chats' , [ { } , octospacc ] ) ;
}
// TODO: we should check origin
// TODO: we should check origin
window . addEventListener ( 'message' , function ( event ) {
window . addEventListener ( 'message' , function ( event ) {
// TODO edit the video embed function to send objects for consistency
// TODO edit the video embed function to send objects for consistency