Repair emoji autocomplete,repair YouPlay,improve Invidious embed,change Vinayaka instance,add Bibliogram and NoFB redirects

This commit is contained in:
nipos 2020-02-09 19:26:29 +01:00
parent 6ffa5dab2f
commit aadcb94355
21 changed files with 563 additions and 89 deletions

View File

@ -28,6 +28,7 @@ We moved our instances list to our webpage: https://www.halcyon.social/instances
or read our new documentation pages to install it manually: https://www.halcyon.social/documentation.php?page=install or read our new documentation pages to install it manually: https://www.halcyon.social/documentation.php?page=install
## Blog ## Blog
- Release of Version 2.4.7 - Repair emoji autocomplete,repair YouPlay,improve Invidious embed,change Vinayaka instance,add Bibliogram and NoFB redirects
- Release of Version 2.4.6 - Replace some removed Mastodon APIs,fix Toot button not locking on CTRL+Enter,make navbar a bit more responsive - Release of Version 2.4.6 - Replace some removed Mastodon APIs,fix Toot button not locking on CTRL+Enter,make navbar a bit more responsive
- Release of Version 2.4.5 - Support for emoji categories,added links to admin panel,rewrite links to Invidious and Nitter at compose,bugfixes - Release of Version 2.4.5 - Support for emoji categories,added links to admin panel,rewrite links to Invidious and Nitter at compose,bugfixes
- Release of Version 2.4.4 - Option to rewrite all Twitter links to Nitter,click on animated GIF works like image now,full height for images option now works for animated GIF - Release of Version 2.4.4 - Option to rewrite all Twitter links to Nitter,click on animated GIF works like image now,full height for images option now works for animated GIF

View File

@ -71,7 +71,7 @@ $(liNode).data("value",prepend+ele[resultname]+" ");
$(liNode).addClass("account_box").append($("<div>").addClass("icon_box").append($("<img>").attr("src",ele.avatar).css("float","left"))) $(liNode).addClass("account_box").append($("<div>").addClass("icon_box").append($("<img>").attr("src",ele.avatar).css("float","left")))
.append($("<div>").addClass("label_box").append($("<span>").addClass("dn").append($("<h3>").html(ele.display_name).addClass("emoji_poss"))).append($("<span>").addClass("un").html(prepend+ele.acct))); .append($("<div>").addClass("label_box").append($("<span>").addClass("dn").append($("<h3>").html(ele.display_name).addClass("emoji_poss"))).append($("<span>").addClass("un").html(prepend+ele.acct)));
} }
else if(resultname == "name") { else if(prepend == "#") {
$(liNode).data("value",prepend+ele[resultname]+" "); $(liNode).data("value",prepend+ele[resultname]+" ");
$(liNode).addClass("account_box").append($("<div>").addClass("icon_box").append($("<span>").addClass("emoji_poss").html("#️⃣").css("float","left").css("font-size","32px"))) $(liNode).addClass("account_box").append($("<div>").addClass("icon_box").append($("<span>").addClass("emoji_poss").html("#️⃣").css("float","left").css("font-size","32px")))
.append($("<div>").addClass("label_box").append($("<span>").addClass("dn").append($("<h3>").html(prepend+ele[resultname])))); .append($("<div>").addClass("label_box").append($("<span>").addClass("dn").append($("<h3>").html(prepend+ele[resultname]))));

View File

@ -83,6 +83,12 @@ const ytbe = $(this).attr('href').match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\
if(ytbe) $(this).attr('target','_self').attr('href',"javascript:openVideo('"+ytbe[2]+"');void(0)"); if(ytbe) $(this).attr('target','_self').attr('href',"javascript:openVideo('"+ytbe[2]+"');void(0)");
const twcom = $(this).attr('href').match(/https?:\/\/(www\.)?twitter\.com\/(.*)/); const twcom = $(this).attr('href').match(/https?:\/\/(www\.)?twitter\.com\/(.*)/);
if(twcom) $(this).attr('target','_self').attr('href',"javascript:openNitter('"+twcom[2]+"');void(0)"); if(twcom) $(this).attr('target','_self').attr('href',"javascript:openNitter('"+twcom[2]+"');void(0)");
const igpost = $(this).attr('href').match(/https?:\/\/(www\.)?instagram\.com\/p\/([a-zA-Z\d_-]+)/);
if(igpost) $(this).attr('target','_self').attr('href',"javascript:openBibliogram('p/"+igpost[2]+"');void(0)");
const igacc = $(this).attr('href').match(/https?:\/\/(www\.)?instagram\.com\/([a-zA-Z\d_\.]+)/);
if(igacc) $(this).attr('target','_self').attr('href',"javascript:openBibliogram('u/"+igacc[2]+"');void(0)");
const fbcom = $(this).attr('href').match(/https?:\/\/(www\.)?facebook\.com\/(.*)/);
if(fbcom) $(this).attr('target','_self').attr('href',"javascript:openNoFB('"+fbcom[2]+"');void(0)");
if(server_setting_unshorten && checkURLshortener($(this).attr('href'))) { if(server_setting_unshorten && checkURLshortener($(this).attr('href'))) {
var linkrand = Math.round(Math.random()*1000000); var linkrand = Math.round(Math.random()*1000000);
$(this).attr("data-random",linkrand); $(this).attr("data-random",linkrand);
@ -489,6 +495,28 @@ $('.overlay_redirect_nitter').data("path",path);
$('.overlay_redirect_nitter').removeClass('invisible'); $('.overlay_redirect_nitter').removeClass('invisible');
} }
} }
function openBibliogram(path) {
if(localStorage.setting_redirect_bibliogram == "true") window.open("https://"+server_setting_bibliogram+"/"+path,"_blank");
else if(localStorage.setting_redirect_bibliogram == "false") window.open("https://www.instagram.com/"+path,"_blank");
else {
$("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view');
$('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_redirect_bibliogram').data("path",path);
$('.overlay_redirect_bibliogram').removeClass('invisible');
}
}
function openNoFB(path) {
if(localStorage.setting_redirect_nofb == "true") window.open("https://nofb.pw/?p="+encodeURIComponent("https://www.facebook.com/"+path),"_blank");
else if(localStorage.setting_redirect_nofb == "false") window.open("https://www.facebook.com/"+path,"_blank");
else {
$("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view');
$('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_redirect_nofb').data("path",path);
$('.overlay_redirect_nofb').removeClass('invisible');
}
}
function checkStatusLinks(text) { function checkStatusLinks(text) {
$("<span>"+text+"</span>").find("a").each(function(i) { $("<span>"+text+"</span>").find("a").each(function(i) {
const ytcom = $(this).attr('href').match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/); const ytcom = $(this).attr('href').match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/);
@ -519,7 +547,7 @@ media_views += (`
else if(source == "youtube" && localStorage.setting_play_invidious == "true") { else if(source == "youtube" && localStorage.setting_play_invidious == "true") {
media_views += (` media_views += (`
<div class="media_attachment" otype="video/gifv" mediacount="0"> <div class="media_attachment" otype="video/gifv" mediacount="0">
<iframe src="https://${server_setting_invidious}/embed/${watchid}" frameborder="0" allowfullscreen></iframe> <iframe src="/media/invidious.php?server=${server_setting_invidious}&id=${watchid}" frameborder="0" allowfullscreen></iframe>
</div>`); </div>`);
} }
else if(source == "vimeo" && server_setting_vimeo == true && localStorage.setting_play_vimeo == "true") { else if(source == "vimeo" && server_setting_vimeo == true && localStorage.setting_play_vimeo == "true") {
@ -547,10 +575,13 @@ textarea.trigger({"type":"keyup","key":":"});
}}); }});
} }
} }
function submitStatusArray(params,callback,invidious="unset",nitter="unset") { function submitStatusArray(params,callback,invidious="unset",nitter="unset",bibliogram="unset",nofb="unset") {
const ytcom = params.status.first().val().match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/); const ytcom = params.status.first().val().match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/);
const ytbe = params.status.first().val().match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/); const ytbe = params.status.first().val().match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/);
const twcom = params.status.first().val().match(/https?:\/\/(www\.)?twitter\.com\/(.*)/); const twcom = params.status.first().val().match(/https?:\/\/(www\.)?twitter\.com\/(.*)/);
const igpost = params.status.first().val().match(/https?:\/\/(www\.)?instagram\.com\/p\/([a-zA-Z\d_-]+)/);
const igacc = params.status.first().val().match(/https?:\/\/(www\.)?instagram\.com\/([a-zA-Z\d_\.]+)/);
const fbcom = params.status.first().val().match(/https?:\/\/(www\.)?facebook\.com\/(.*)/);
if((ytcom || ytbe) && localStorage.setting_rewrite_invidious == "unset" && invidious == "unset") { if((ytcom || ytbe) && localStorage.setting_rewrite_invidious == "unset" && invidious == "unset") {
$("#js-overlay_content_wrap .temporary_object").empty(); $("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view'); $('#js-overlay_content_wrap').addClass('view');
@ -558,6 +589,8 @@ $('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_rewrite_invidious').data("params",params); $('.overlay_rewrite_invidious').data("params",params);
$('.overlay_rewrite_invidious').data("callback",callback); $('.overlay_rewrite_invidious').data("callback",callback);
$('.overlay_rewrite_invidious').data("nitter",nitter); $('.overlay_rewrite_invidious').data("nitter",nitter);
$('.overlay_rewrite_invidious').data("bibliogram",bibliogram);
$('.overlay_rewrite_invidious').data("nofb",nofb);
$('.overlay_rewrite_invidious').removeClass('invisible'); $('.overlay_rewrite_invidious').removeClass('invisible');
} }
else if(twcom && localStorage.setting_rewrite_nitter == "unset" && nitter == "unset") { else if(twcom && localStorage.setting_rewrite_nitter == "unset" && nitter == "unset") {
@ -567,23 +600,59 @@ $('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_rewrite_nitter').data("params",params); $('.overlay_rewrite_nitter').data("params",params);
$('.overlay_rewrite_nitter').data("callback",callback); $('.overlay_rewrite_nitter').data("callback",callback);
$('.overlay_rewrite_nitter').data("invidious",invidious); $('.overlay_rewrite_nitter').data("invidious",invidious);
$('.overlay_rewrite_nitter').data("bibliogram",bibliogram);
$('.overlay_rewrite_nitter').data("nofb",nofb);
$('.overlay_rewrite_nitter').removeClass('invisible'); $('.overlay_rewrite_nitter').removeClass('invisible');
} }
else if((igpost || igacc) && localStorage.setting_rewrite_bibliogram == "unset" && bibliogram == "unset") {
$("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view');
$('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_rewrite_bibliogram').data("params",params);
$('.overlay_rewrite_bibliogram').data("callback",callback);
$('.overlay_rewrite_bibliogram').data("invidious",invidious);
$('.overlay_rewrite_bibliogram').data("nitter",nitter);
$('.overlay_rewrite_bibliogram').data("nofb",nofb);
$('.overlay_rewrite_bibliogram').removeClass('invisible');
}
else if(fbcom && localStorage.setting_rewrite_nofb == "unset" && nofb == "unset") {
$("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view');
$('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_rewrite_nofb').data("params",params);
$('.overlay_rewrite_nofb').data("callback",callback);
$('.overlay_rewrite_nofb').data("invidious",invidious);
$('.overlay_rewrite_nofb').data("nitter",nitter);
$('.overlay_rewrite_nofb').data("bibliogram",bibliogram);
$('.overlay_rewrite_nofb').removeClass('invisible');
}
if(ytcom && (localStorage.setting_rewrite_invidious == "true" || invidious == "true")) { if(ytcom && (localStorage.setting_rewrite_invidious == "true" || invidious == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/,"https://"+server_setting_invidious+"/watch?v=$2")); params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/,"https://"+server_setting_invidious+"/watch?v=$2"));
submitStatusArray(params,callback,invidious,nitter); submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
} }
else if(ytbe && (localStorage.setting_rewrite_invidious == "true" || invidious == "true")) { else if(ytbe && (localStorage.setting_rewrite_invidious == "true" || invidious == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/,"https://"+server_setting_invidious+"/watch?v=$2")); params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/,"https://"+server_setting_invidious+"/watch?v=$2"));
submitStatusArray(params,callback,invidious,nitter); submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
} }
else if(twcom && (localStorage.setting_rewrite_nitter == "true" || nitter == "true")) { else if(twcom && (localStorage.setting_rewrite_nitter == "true" || nitter == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?twitter\.com\/(.*)/,"https://"+server_setting_nitter+"/$2")); params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?twitter\.com\/(.*)/,"https://"+server_setting_nitter+"/$2"));
submitStatusArray(params,callback,invidious,nitter); submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
} }
else if(((!ytcom && !ytbe) || localStorage.setting_rewrite_invidious == "false" || invidious == "false") && (!twcom || localStorage.setting_rewrite_nitter == "false" || nitter == "false")) submitStatusArrayNow(params,callback); else if(igpost && (localStorage.setting_rewrite_bibliogram == "true" || bibliogram == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?instagram\.com\/p\/([a-zA-Z\d_-]+)/,"https://"+server_setting_bibliogram+"/p/$2"));
submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
} }
function submitStatusArrayNow(params,callback,invidious,nitter) { else if(igacc && (localStorage.setting_rewrite_bibliogram == "true" || bibliogram == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?instagram\.com\/([a-zA-Z\d_\.]+)/,"https://"+server_setting_bibliogram+"/u/$2"));
submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
}
else if(fbcom && (localStorage.setting_rewrite_nofb == "true" || nofb == "true")) {
params.status.first().val(params.status.first().val().replace(/https?:\/\/(www\.)?facebook\.com\/(.*)/,"https://nofb.pw/?p=https%3A%2F%2Fwww.facebook.com%2F$2"));
submitStatusArray(params,callback,invidious,nitter,bibliogram,nofb);
}
else if(((!ytcom && !ytbe) || localStorage.setting_rewrite_invidious == "false" || invidious == "false") && (!twcom || localStorage.setting_rewrite_nitter == "false" || nitter == "false") && ((!igpost && !igacc) || localStorage.setting_rewrite_bibliogram == "false" || bibliogram == "false") && (!fbcom || localStorage.setting_rewrite_nofb == "false" || nofb == "false")) submitStatusArrayNow(params,callback,invidious,nitter,bibliogram,nofb);
}
function submitStatusArrayNow(params,callback,invidious,nitter,bibliogram,nofb) {
var statuses = params.status; var statuses = params.status;
params.status = params.status.first().val(); params.status = params.status.first().val();
api.post("statuses",params,function(data) { api.post("statuses",params,function(data) {
@ -597,7 +666,7 @@ nparams.status = statuses;
nparams.visibility = params.visibility; nparams.visibility = params.visibility;
nparams.spoiler_text = params.spoiler_text; nparams.spoiler_text = params.spoiler_text;
nparams.in_reply_to_id = data.id; nparams.in_reply_to_id = data.id;
submitStatusArray(nparams,callback,invidious,nitter); submitStatusArray(nparams,callback,invidious,nitter,bibliogram,nofb);
} }
}); });
} }

View File

@ -22,6 +22,18 @@ $("#setting_rewrite_nitter")[0].checked = true;
if(localStorage.setting_rewrite_nitter != "unset") { if(localStorage.setting_rewrite_nitter != "unset") {
$("#setting_rewrite_nitter_reset").show(); $("#setting_rewrite_nitter_reset").show();
} }
if(localStorage.setting_rewrite_bibliogram == "true") {
$("#setting_rewrite_bibliogram")[0].checked = true;
}
if(localStorage.setting_rewrite_bibliogram != "unset") {
$("#setting_rewrite_bibliogram_reset").show();
}
if(localStorage.setting_rewrite_nofb == "true") {
$("#setting_rewrite_nofb")[0].checked = true;
}
if(localStorage.setting_rewrite_nofb != "unset") {
$("#setting_rewrite_nofb_reset").show();
}
if(localStorage.setting_who_to_follow == "true") { if(localStorage.setting_who_to_follow == "true") {
$("#setting_who_to_follow")[0].checked = true; $("#setting_who_to_follow")[0].checked = true;
} }
@ -87,6 +99,40 @@ $("#setting_rewrite_nitter_reset").fadeOut();
$("#setting_rewrite_nitter")[0].checked = false; $("#setting_rewrite_nitter")[0].checked = false;
putMessage(__("Twitter link rewrite reset to default")); putMessage(__("Twitter link rewrite reset to default"));
}); });
$("#setting_rewrite_bibliogram").change(function() {
$("#setting_rewrite_bibliogram_reset").fadeIn();
if(this.checked) {
localStorage.setItem("setting_rewrite_bibliogram","true");
putMessage(__("Instagram links rewritten to Bibliogram"));
}
else {
localStorage.setItem("setting_rewrite_bibliogram","false");
putMessage(__("Instagram links not rewritten anymore"));
}
});
$("#setting_rewrite_bibliogram_reset").click(function() {
localStorage.setItem("setting_rewrite_bibliogram","unset");
$("#setting_rewrite_bibliogram_reset").fadeOut();
$("#setting_rewrite_bibliogram")[0].checked = false;
putMessage(__("Instagram link rewrite reset to default"));
});
$("#setting_rewrite_nofb").change(function() {
$("#setting_rewrite_nofb_reset").fadeIn();
if(this.checked) {
localStorage.setItem("setting_rewrite_nofb","true");
putMessage(__("Facebook links rewritten to NoFB"));
}
else {
localStorage.setItem("setting_rewrite_nofb","false");
putMessage(__("Facebook links not rewritten anymore"));
}
});
$("#setting_rewrite_nofb_reset").click(function() {
localStorage.setItem("setting_rewrite_nofb","unset");
$("#setting_rewrite_nofb_reset").fadeOut();
$("#setting_rewrite_nofb")[0].checked = false;
putMessage(__("Facebook link rewrite reset to default"));
});
$(document).on('change',".local_instance_wrap input[name='local_instance']", function(e) { $(document).on('change',".local_instance_wrap input[name='local_instance']", function(e) {
if($(this).val()) { if($(this).val()) {
localStorage.setItem("setting_local_instance","https://"+$(this).val()); localStorage.setItem("setting_local_instance","https://"+$(this).val());
@ -514,6 +560,18 @@ $("#setting_redirect_nitter")[0].checked = true;
if(localStorage.setting_redirect_nitter != "unset") { if(localStorage.setting_redirect_nitter != "unset") {
$("#setting_redirect_nitter_reset").show(); $("#setting_redirect_nitter_reset").show();
} }
if(localStorage.setting_redirect_bibliogram == "true") {
$("#setting_redirect_bibliogram")[0].checked = true;
}
if(localStorage.setting_redirect_bibliogram != "unset") {
$("#setting_redirect_bibliogram_reset").show();
}
if(localStorage.setting_redirect_nofb == "true") {
$("#setting_redirect_nofb")[0].checked = true;
}
if(localStorage.setting_redirect_nofb != "unset") {
$("#setting_redirect_nofb_reset").show();
}
}); });
$("#setting_play_gif").change(function() { $("#setting_play_gif").change(function() {
if(this.checked) { if(this.checked) {
@ -619,6 +677,40 @@ $("#setting_redirect_nitter_reset").fadeOut();
$("#setting_redirect_nitter")[0].checked = false; $("#setting_redirect_nitter")[0].checked = false;
putMessage(__("Twitter link redirect reset to default")); putMessage(__("Twitter link redirect reset to default"));
}); });
$("#setting_redirect_bibliogram").change(function() {
$("#setting_redirect_bibliogram_reset").fadeIn();
if(this.checked) {
localStorage.setItem("setting_redirect_bibliogram","true");
putMessage(__("Instagram links redirected to Bibliogram"));
}
else {
localStorage.setItem("setting_redirect_bibliogram","false");
putMessage(__("Instagram links not redirected anymore"));
}
});
$("#setting_redirect_bibliogram_reset").click(function() {
localStorage.setItem("setting_redirect_bibliogram","unset");
$("#setting_redirect_bibliogram_reset").fadeOut();
$("#setting_redirect_bibliogram")[0].checked = false;
putMessage(__("Instagram link redirect reset to default"));
});
$("#setting_redirect_nofb").change(function() {
$("#setting_redirect_nofb_reset").fadeIn();
if(this.checked) {
localStorage.setItem("setting_redirect_nofb","true");
putMessage(__("Facebook links redirected to NoFB"));
}
else {
localStorage.setItem("setting_redirect_nofb","false");
putMessage(__("Facebook links not redirected anymore"));
}
});
$("#setting_redirect_nofb_reset").click(function() {
localStorage.setItem("setting_redirect_nofb","unset");
$("#setting_redirect_nofb_reset").fadeOut();
$("#setting_redirect_nofb")[0].checked = false;
putMessage(__("Facebook link redirect reset to default"));
});
} }
else if(window.location.pathname == "/settings/blocks") { else if(window.location.pathname == "/settings/blocks") {
$('#js-settings_nav_blocks').toggleClass('view'); $('#js-settings_nav_blocks').toggleClass('view');

View File

@ -2015,8 +2015,12 @@ $('#js-overlay_content_wrap .overlay_addlist').addClass('invisible');
$('#js-overlay_content_wrap .overlay_filter').addClass('invisible'); $('#js-overlay_content_wrap .overlay_filter').addClass('invisible');
$('#js-overlay_content_wrap .overlay_redirect_invidious').addClass('invisible'); $('#js-overlay_content_wrap .overlay_redirect_invidious').addClass('invisible');
$('#js-overlay_content_wrap .overlay_redirect_nitter').addClass('invisible'); $('#js-overlay_content_wrap .overlay_redirect_nitter').addClass('invisible');
$('#js-overlay_content_wrap .overlay_redirect_bibliogram').addClass('invisible');
$('#js-overlay_content_wrap .overlay_redirect_nofb').addClass('invisible');
$('#js-overlay_content_wrap .overlay_rewrite_invidious').addClass('invisible'); $('#js-overlay_content_wrap .overlay_rewrite_invidious').addClass('invisible');
$('#js-overlay_content_wrap .overlay_rewrite_nitter').addClass('invisible'); $('#js-overlay_content_wrap .overlay_rewrite_nitter').addClass('invisible');
$('#js-overlay_content_wrap .overlay_rewrite_bibliogram').addClass('invisible');
$('#js-overlay_content_wrap .overlay_rewrite_nofb').addClass('invisible');
$('#js-overlay_content .temporary_object, #js-overlay_content .parmanent_object').removeClass('visible'); $('#js-overlay_content .temporary_object, #js-overlay_content .parmanent_object').removeClass('visible');
$('#js-overlay_content_wrap .overlay_status.submit_status_label').removeClass('active_submit_button'); $('#js-overlay_content_wrap .overlay_status.submit_status_label').removeClass('active_submit_button');
$('#js-overlay_content_wrap .single_reply_status .submit_status_label').removeClass('active_submit_button'); $('#js-overlay_content_wrap .single_reply_status .submit_status_label').removeClass('active_submit_button');
@ -2084,26 +2088,66 @@ $('.close_button').click();
window.open("https://twitter.com/"+$(".overlay_redirect_nitter").data("path"),"_blank"); window.open("https://twitter.com/"+$(".overlay_redirect_nitter").data("path"),"_blank");
if($("#redirect_nitter_permanent")[0].checked) localStorage.setting_redirect_nitter = "false"; if($("#redirect_nitter_permanent")[0].checked) localStorage.setting_redirect_nitter = "false";
}); });
$('.overlay_redirect_bibliogram_yes').click(function() {
$('.close_button').click();
window.open("https://"+server_setting_bibliogram+"/"+$(".overlay_redirect_bibliogram").data("path"),"_blank");
if($("#redirect_bibliogram_permanent")[0].checked) localStorage.setting_redirect_bibliogram = "true";
});
$('.overlay_redirect_bibliogram_no').click(function() {
$('.close_button').click();
window.open("https://www.instagram.com/"+$(".overlay_redirect_bibliogram").data("path"),"_blank");
if($("#redirect_bibliogram_permanent")[0].checked) localStorage.setting_redirect_bibliogram = "false";
});
$('.overlay_redirect_nofb_yes').click(function() {
$('.close_button').click();
window.open("https://nofb.pw/?p="+encodeURIComponent("https://www.facebook.com/"+$(".overlay_redirect_nofb").data("path")),"_blank");
if($("#redirect_nofb_permanent")[0].checked) localStorage.setting_redirect_nofb = "true";
});
$('.overlay_redirect_nofb_no').click(function() {
$('.close_button').click();
window.open("https://www.facebook.com/"+$(".overlay_redirect_nofb").data("path"),"_blank");
if($("#redirect_nofb_permanent")[0].checked) localStorage.setting_redirect_nofb = "false";
});
$('.overlay_rewrite_invidious_yes').click(function() { $('.overlay_rewrite_invidious_yes').click(function() {
$('.close_button').click(); $('.close_button').click();
submitStatusArray($(".overlay_rewrite_invidious").data("params"),$(".overlay_rewrite_invidious").data("callback"),"true",$(".overlay_rewrite_invidious").data("nitter")); submitStatusArray($(".overlay_rewrite_invidious").data("params"),$(".overlay_rewrite_invidious").data("callback"),"true",$(".overlay_rewrite_invidious").data("nitter"),$(".overlay_rewrite_invidious").data("bibliogram"),$(".overlay_rewrite_invidious").data("nofb"));
if($("#rewrite_invidious_permanent")[0].checked) localStorage.setting_rewrite_invidious = "true"; if($("#rewrite_invidious_permanent")[0].checked) localStorage.setting_rewrite_invidious = "true";
}); });
$('.overlay_rewrite_invidious_no').click(function() { $('.overlay_rewrite_invidious_no').click(function() {
$('.close_button').click(); $('.close_button').click();
submitStatusArray($(".overlay_rewrite_invidious").data("params"),$(".overlay_rewrite_invidious").data("callback"),"false",$(".overlay_rewrite_invidious").data("nitter")); submitStatusArray($(".overlay_rewrite_invidious").data("params"),$(".overlay_rewrite_invidious").data("callback"),"false",$(".overlay_rewrite_invidious").data("nitter"),$(".overlay_rewrite_invidious").data("bibliogram"),$(".overlay_rewrite_invidious").data("nofb"));
if($("#rewrite_invidious_permanent")[0].checked) localStorage.setting_rewrite_invidious = "false"; if($("#rewrite_invidious_permanent")[0].checked) localStorage.setting_rewrite_invidious = "false";
}); });
$('.overlay_rewrite_nitter_yes').click(function() { $('.overlay_rewrite_nitter_yes').click(function() {
$('.close_button').click(); $('.close_button').click();
submitStatusArray($(".overlay_rewrite_nitter").data("params"),$(".overlay_rewrite_nitter").data("callback"),$(".overlay_rewrite_nitter").data("invidious"),"true"); submitStatusArray($(".overlay_rewrite_nitter").data("params"),$(".overlay_rewrite_nitter").data("callback"),$(".overlay_rewrite_nitter").data("invidious"),"true",$(".overlay_rewrite_nitter").data("bibliogram"),$(".overlay_rewrite_nitter").data("bibliogram"));
if($("#rewrite_nitter_permanent")[0].checked) localStorage.setting_rewrite_nitter = "true"; if($("#rewrite_nitter_permanent")[0].checked) localStorage.setting_rewrite_nitter = "true";
}); });
$('.overlay_rewrite_nitter_no').click(function() { $('.overlay_rewrite_nitter_no').click(function() {
$('.close_button').click(); $('.close_button').click();
submitStatusArray($(".overlay_rewrite_nitter").data("params"),$(".overlay_rewrite_nitter").data("callback"),$(".overlay_rewrite_nitter").data("invidious"),"false"); submitStatusArray($(".overlay_rewrite_nitter").data("params"),$(".overlay_rewrite_nitter").data("callback"),$(".overlay_rewrite_nitter").data("invidious"),"false",$(".overlay_rewrite_nitter").data("bibliogram"),$(".overlay_rewrite_nitter").data("bibliogram"));
if($("#rewrite_nitter_permanent")[0].checked) localStorage.setting_rewrite_nitter = "false"; if($("#rewrite_nitter_permanent")[0].checked) localStorage.setting_rewrite_nitter = "false";
}); });
$('.overlay_rewrite_bibliogram_yes').click(function() {
$('.close_button').click();
submitStatusArray($(".overlay_rewrite_bibliogram").data("params"),$(".overlay_rewrite_bibliogram").data("callback"),$(".overlay_rewrite_bibliogram").data("invidious"),$(".overlay_rewrite_bibliogram").data("nitter"),"true",$(".overlay_rewrite_bibliogram").data("nofb"));
if($("#rewrite_bibliogram_permanent")[0].checked) localStorage.setting_rewrite_bibliogram = "true";
});
$('.overlay_rewrite_bibliogram_no').click(function() {
$('.close_button').click();
submitStatusArray($(".overlay_rewrite_bibliogram").data("params"),$(".overlay_rewrite_bibliogram").data("callback"),$(".overlay_rewrite_bibliogram").data("invidious"),$(".overlay_rewrite_bibliogram").data("nitter"),"false",$(".overlay_rewrite_bibliogram").data("nofb"));
if($("#rewrite_bibliogram_permanent")[0].checked) localStorage.setting_rewrite_bibliogram = "false";
});
$('.overlay_rewrite_nofb_yes').click(function() {
$('.close_button').click();
submitStatusArray($(".overlay_rewrite_nofb").data("params"),$(".overlay_rewrite_nofb").data("callback"),$(".overlay_rewrite_nofb").data("invidious"),$(".overlay_rewrite_nofb").data("nitter"),$(".overlay_rewrite_nofb").data("bibliogram"),"true");
if($("#rewrite_nofb_permanent")[0].checked) localStorage.setting_rewrite_nofb = "true";
});
$('.overlay_rewrite_nofb_no').click(function() {
$('.close_button').click();
submitStatusArray($(".overlay_rewrite_nofb").data("params"),$(".overlay_rewrite_nofb").data("callback"),$(".overlay_rewrite_nofb").data("invidious"),$(".overlay_rewrite_nofb").data("nitter"),$(".overlay_rewrite_nofb").data("bibliogram"),"false");
if($("#rewrite_nofb_permanent")[0].checked) localStorage.setting_rewrite_nofb = "false";
});
if($("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden"); if($("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden");
$("#js-overlay_content_wrap").attrchange(function(attr) { $("#js-overlay_content_wrap").attrchange(function(attr) {
if(attr == "class" && $("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden"); if(attr == "class" && $("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden");
@ -2150,9 +2194,15 @@ e.stopPropagation();
const ytcom = $(this).data("url").match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/); const ytcom = $(this).data("url").match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/);
const ytbe = $(this).data("url").match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/); const ytbe = $(this).data("url").match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/);
const twcom = $(this).data("url").match(/https?:\/\/(www\.)?twitter\.com\/(.*)/); const twcom = $(this).data("url").match(/https?:\/\/(www\.)?twitter\.com\/(.*)/);
const igpost = $(this).data("url").match(/https?:\/\/(www\.)?instagram\.com\/p\/([a-zA-Z\d_-]+)/);
const igacc = $(this).data("url").match(/https?:\/\/(www\.)?instagram\.com\/([a-zA-Z\d_\.]+)/);
const fbcom = $(this).data("url").match(/https?:\/\/(www\.)?facebook\.com\/(.*)/);
if(ytcom) openVideo(ytcom[2]); if(ytcom) openVideo(ytcom[2]);
else if(ytbe) openVideo(ytbe[2]); else if(ytbe) openVideo(ytbe[2]);
else if(twcom) openNitter(twcom[2]); else if(twcom) openNitter(twcom[2]);
else if(igpost) openBibliogram("p/"+igpost[2]);
else if(igacc) openBibliogram("u/"+igacc[2]);
else if(fbcom) openNoFB(fbcom[2]);
else window.open($(this).data("url"),"_blank"); else window.open($(this).data("url"),"_blank");
}); });
$(document).on('focus','.status_textarea textarea,.status_top .status_spoiler',function(e) { $(document).on('focus','.status_textarea textarea,.status_top .status_spoiler',function(e) {

View File

@ -3,7 +3,7 @@
[App] [App]
api_client_name = Your application name api_client_name = Your application name
api_client_website = https://example.com/ api_client_website = https://example.com/
who_to_follow_provider = https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-osa-api.cgi?{{host}}+{{user}} who_to_follow_provider = https://vinayaka.tsia.de/cgi-bin/vinayaka-user-match-osa-api.cgi?{{host}}+{{user}}
default_language = en_US default_language = en_US
debug_mode = false debug_mode = false
url_unshortener = true url_unshortener = true
@ -11,13 +11,17 @@ url_unshortener = true
; Media embed settings ; Media embed settings
; YouPlay resolves YouTube MP4s on your server and sends this link to the user for privacy-friendly watching ; YouPlay resolves YouTube MP4s on your server and sends this link to the user for privacy-friendly watching
; Vimeo embeds work in the same way as YouPlay embeds here because the official players contain too much spyware ; Vimeo embeds work in the same way as YouPlay embeds here because the official players contain too much spyware
; YouPlay Fallback uses a proprietary API of https://unblockvideos.com and can be used if your own server IP has been blocked by Google
; Invidous is a external service to watch YouTube videos in a privacy-friendly way - Halcyon can automatically rewrite links to a instance you can set here ; Invidous is a external service to watch YouTube videos in a privacy-friendly way - Halcyon can automatically rewrite links to a instance you can set here
; Nitter is a external service to view Twitter contents in a privacy-friendly way - Halcyon can automatically rewrite links to a instance you can set here ; Nitter is a external service to view Twitter contents in a privacy-friendly way - Halcyon can automatically rewrite links to a instance you can set here
; Bibliogram is a external service to view Instagram contents in a privacy-friendly way - Halcyon can automatically rewrite links to a instance you can set here
[Media] [Media]
youplay = true youplay = true
vimeo = true vimeo = true
youplay_fallback = true
invidious = invidiou.sh invidious = invidiou.sh
nitter = nitter.nixnet.xyz nitter = nitter.13ad.de
bibliogram = bibliogram.dsrev.ru
; The proxy can be used optionally to resolve data for privacy-friendly media embeds on the server side - It is not used for Mastodon API requests on login ; The proxy can be used optionally to resolve data for privacy-friendly media embeds on the server side - It is not used for Mastodon API requests on login
; Proxy type can be set to none, socks5, socks4, http or https - Example settings for locally installed Tor client ; Proxy type can be set to none, socks5, socks4, http or https - Example settings for locally installed Tor client

View File

@ -17,8 +17,12 @@ include dirname(__FILE__).('/widgets/overlay_prompt.php');
include dirname(__FILE__).('/widgets/overlay_addlist.php'); include dirname(__FILE__).('/widgets/overlay_addlist.php');
include dirname(__FILE__).('/widgets/overlay_redirect_invidious.php'); include dirname(__FILE__).('/widgets/overlay_redirect_invidious.php');
include dirname(__FILE__).('/widgets/overlay_redirect_nitter.php'); include dirname(__FILE__).('/widgets/overlay_redirect_nitter.php');
include dirname(__FILE__).('/widgets/overlay_redirect_bibliogram.php');
include dirname(__FILE__).('/widgets/overlay_redirect_nofb.php');
include dirname(__FILE__).('/widgets/overlay_rewrite_invidious.php'); include dirname(__FILE__).('/widgets/overlay_rewrite_invidious.php');
include dirname(__FILE__).('/widgets/overlay_rewrite_nitter.php'); include dirname(__FILE__).('/widgets/overlay_rewrite_nitter.php');
include dirname(__FILE__).('/widgets/overlay_rewrite_bibliogram.php');
include dirname(__FILE__).('/widgets/overlay_rewrite_nofb.php');
if($_SERVER["REQUEST_URI"] == "/settings/filters") include dirname(__FILE__).('/widgets/overlay_filter.php'); if($_SERVER["REQUEST_URI"] == "/settings/filters") include dirname(__FILE__).('/widgets/overlay_filter.php');
?> ?>
</div> </div>

View File

@ -75,7 +75,8 @@ server_setting_youplay = <?=$config["Media"]["youplay"] ? "true" : "false"?>;
server_setting_vimeo = <?=$config["Media"]["vimeo"] ? "true" : "false"?>; server_setting_vimeo = <?=$config["Media"]["vimeo"] ? "true" : "false"?>;
server_setting_unshorten = <?=$config["App"]["url_unshortener"] ? "true" : "false"?>; server_setting_unshorten = <?=$config["App"]["url_unshortener"] ? "true" : "false"?>;
server_setting_invidious = <?=$config["Media"]["invidious"] ? "'".$config["Media"]["invidious"]."'" : "'invidiou.sh'"?>; server_setting_invidious = <?=$config["Media"]["invidious"] ? "'".$config["Media"]["invidious"]."'" : "'invidiou.sh'"?>;
server_setting_nitter = <?=$config["Media"]["nitter"] ? "'".$config["Media"]["nitter"]."'" : "'nitter.nixnet.xyz'"?>; server_setting_nitter = <?=$config["Media"]["nitter"] ? "'".$config["Media"]["nitter"]."'" : "'nitter.13ad.de'"?>;
server_setting_bibliogram = <?=$config["Media"]["bibliogram"] ? "'".$config["Media"]["bibliogram"]."'" : "'bibliogram.dsrev.ru'"?>;
</script> </script>
</head> </head>
<body> <body>

View File

@ -60,8 +60,12 @@ localStorage.setItem('setting_post_privacy','".$profile["source"]["privacy"]."')
localStorage.setItem('setting_post_sensitive','".$profile["source"]["sensitive"]."'); localStorage.setItem('setting_post_sensitive','".$profile["source"]["sensitive"]."');
localStorage.setItem('setting_redirect_invidious','unset'); localStorage.setItem('setting_redirect_invidious','unset');
localStorage.setItem('setting_redirect_nitter','unset'); localStorage.setItem('setting_redirect_nitter','unset');
localStorage.setItem('setting_redirect_bibliogram','unset');
localStorage.setItem('setting_redirect_nofb','unset');
localStorage.setItem('setting_rewrite_invidious','unset'); localStorage.setItem('setting_rewrite_invidious','unset');
localStorage.setItem('setting_rewrite_nitter','unset'); localStorage.setItem('setting_rewrite_nitter','unset');
localStorage.setItem('setting_rewrite_bibliogram','unset');
localStorage.setItem('setting_rewrite_nofb','unset');
$.cookie('darktheme','unset',{path:'/',expires:3650}); $.cookie('darktheme','unset',{path:'/',expires:3650});
if(sessionStorage.return && sessionStorage.return == 'share') location.href = '/intent/toot?action=send'; if(sessionStorage.return && sessionStorage.return == 'share') location.href = '/intent/toot?action=send';
else location.href = '/'; else location.href = '/';

95
media/invidious.php Normal file
View File

@ -0,0 +1,95 @@
<?php
if(!isset($_COOKIE["session"]) || $_COOKIE["session"] != "true") {
http_response_code(403);
die('Forbidden');
}
?>
<!DOCTYPE html>
<html lang="en" style="height:100%">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/assets/js/player/youplay.js"></script>
</head>
<body style="margin:0;height:100%;overflow:hidden">
<video class="video-js vjs-default-skin" controls id="player" style="width:100%;height:100%;display:none">
Your browser does not support the video tag.
</video>
<script>
var itag_info = {
5:"FLV[400x240]",
6:"FLV[450x270]",
17:"3GP[176x144]",
18:"MP4[640x360]",
22:"HD MP4[1280x720]",
34:"FLV[640x360]",
35:"FLV[854x480]",
36:"3GP[320x180]",
37:"MP4[1920x1080]",
38:"MP4[4096x3072]",
43:"WEBM[640x360]",
44:"WEBM[854x480]",
45:"WEBM[1280x720]",
46:"WEBM[1920x1080]",
59:"MP4[854x480]",
78:"MP4[854x480]",
137:"(Video Only) MP4[1920x1080]",
248:"(Video Only) WEBM[1920x1080]",
136:"(Video Only) MP4[1280x720]",
247:"(Video Only) WEBM[1280x720]",
135:"(Video Only) MP4[854x480]",
244:"(Video Only) WEBM[854x480]",
134:"(Video Only) MP4[640x360]",
243:"(Video Only) WEBM[640x360]",
133:"(Video Only) MP4[320x240]",
242:"(Video Only) WEBM[320x240]",
160:"(Video Only) MP4[176x144]",
278:"(Video Only) WEBM[176x144]",
140:"(Audio Only) M4A[128Kbps]",
171:"(Audio Only) WEBM[128Kbps]",
249:"(Audio Only) WEBM[50Kbps]",
250:"(Audio Only) WEBM[70Kbps]",
251:"(Audio Only) WEBM[160Kbps]"
};
var xhr = new XMLHttpRequest();
xhr.open('GET','https://<?=$_GET["server"]?>/api/v1/videos/<?=$_GET["id"]?>');
xhr.onload = function() {
if(xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
document.getElementById("player").setAttribute("title",data.title);
document.getElementById("player").setAttribute("poster",data.videoThumbnails[1].url);
for(var i=0;i<data.captions.length;i++) {
var caption = document.createElement("track");
caption.setAttribute("kind","captions");
caption.setAttribute("label",data.captions[i].label);
caption.src = "https://<?=$_GET["server"]?>"+data.captions[i].url;
document.getElementById("player").appendChild(caption);
}
var streams = new Array;
var audios = new Array;
for(var i=0;i<data.formatStreams.length;i++) {
var stream = new Object();
stream.src = data.formatStreams[i].url.replace(/(https\:\/\/)[^\.]+(\.googlevideo\.com)/,"https://redirector$2");
stream.label = itag_info[data.formatStreams[i].itag];
stream.audio = true;
streams.push(stream);
}
for(var i=0;i<data.adaptiveFormats.length;i++) {
var stream = new Object();
stream.src = data.adaptiveFormats[i].url.replace(/(https\:\/\/)[^\.]+(\.googlevideo\.com)/,"https://redirector$2");
stream.label = itag_info[data.adaptiveFormats[i].itag];
stream.audio = false;
if(stream.label) {
if(stream.label.indexOf("(Audio Only)") != -1) audios.push(stream.src);
else streams.push(stream);
}
}
document.getElementById("player").style.display = "block";
yp_player({share:false,use_desktop_skin:true,sources:streams,audio_url:audios});
}
else document.write("Sorry, there was an error while trying to load your video.");
}
xhr.send();
</script>
</body>
</html>

View File

@ -19,7 +19,7 @@ $vdata = vimeo(htmlspecialchars($_GET["id"]));
if($vdata) { if($vdata) {
$vlink = $vdata["dl"]; $vlink = $vdata["dl"];
?> ?>
<video class="video-js vjs-default-skin" controls id="player" poster="image.php?url=<?=urlencode($vdata["info"]["Thumbnail"])?>" title="<?=$vdata["info"]["Title"]?>" style="width:100%;height:100%"> <video class="video-js vjs-default-skin" controls id="player" poster="image.php?url=<?=urlencode($vdata["info"]["Thumbnail"])?>" title="<?=htmlspecialchars($vdata["info"]["Title"])?>" style="width:100%;height:100%">
<?php <?php
for($i=0;$i<count($vdata["info"]["Captions"]);$i++) { for($i=0;$i<count($vdata["info"]["Captions"]);$i++) {
echo "<track kind='captions' label='".$vdata["info"]["Captions"][$i]["title"]."' src='vimeocaption.php?url=".urlencode($vdata["info"]["Captions"][$i]["url"])."'>"; echo "<track kind='captions' label='".$vdata["info"]["Captions"][$i]["title"]."' src='vimeocaption.php?url=".urlencode($vdata["info"]["Captions"][$i]["url"])."'>";

View File

@ -17,10 +17,10 @@ die('Forbidden');
include("ytclass.php"); include("ytclass.php");
$ytclass = new YTDownloader(); $ytclass = new YTDownloader();
$vdata = $ytclass->getDownloadLinks(htmlspecialchars($_GET["id"])); $vdata = $ytclass->getDownloadLinks(htmlspecialchars($_GET["id"]));
if($vdata) { if($vdata && is_array($vdata)) {
$vlink = $vdata["dl"]; $vlink = $vdata["dl"];
?> ?>
<video class="video-js vjs-default-skin" controls id="player" poster="image.php?url=<?=urlencode($vdata["info"]["Thumbnail"])?>" title="<?=$vdata["info"]["Title"]?>" style="width:100%;height:100%"> <video class="video-js vjs-default-skin" controls id="player" poster="image.php?url=<?=urlencode($vdata["info"]["Thumbnail"])?>" title="<?=htmlspecialchars($vdata["info"]["Title"])?>" style="width:100%;height:100%">
<?php <?php
for($i=0;$i<count($vdata["info"]["Captions"]);$i++) { for($i=0;$i<count($vdata["info"]["Captions"]);$i++) {
echo "<track kind='captions' label='".$vdata["info"]["Captions"][$i]["title"]."' src='ytcaption.php?lang=".$vdata["info"]["Captions"][$i]["lang"]."&url=".urlencode($vdata["info"]["Captions"][$i]["url"])."'>"; echo "<track kind='captions' label='".$vdata["info"]["Captions"][$i]["title"]."' src='ytcaption.php?lang=".$vdata["info"]["Captions"][$i]["lang"]."&url=".urlencode($vdata["info"]["Captions"][$i]["url"])."'>";
@ -48,7 +48,11 @@ if(strstr($vlink[$i]["type"],"(Audio Only)")) echo "'".$vlink[$i]["url"]."',";
?> ?>
],thumbnails:JSON.parse('<?=json_encode($vdata["info"]["Thumbs"])?>')}); ],thumbnails:JSON.parse('<?=json_encode($vdata["info"]["Thumbs"])?>')});
</script> </script>
<?php } else { ?> <?php
}
else if($vdata && !is_array($vdata)) echo "<script>window.location.href='invidious.php?server=".urlencode($vdata)."&id=".urlencode($_GET["id"])."'</script>";
else {
?>
Sorry, there was an error while trying to load your video. Sorry, there was an error while trying to load your video.
<?php } ?> <?php } ?>
</body> </body>

View File

@ -20,8 +20,8 @@ return $result;
return FALSE; return FALSE;
} }
function timevtt($gtime) { function timevtt($gtime) {
if(strlen(date("H",intval($gtime))-1) == 1) $hour = "0".intval(date("H",intval($gtime))-1); if(strlen(date("H",intval($gtime))) == 1) $hour = "0".intval(date("H",intval($gtime)));
else $hour = intval(date("H",intval($gtime))-1); else $hour = intval(date("H",intval($gtime)));
if(strlen(explode(".",$gtime)[1]) == 3) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1]; if(strlen(explode(".",$gtime)[1]) == 3) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1];
if(strlen(explode(".",$gtime)[1]) == 2) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1]."0"; if(strlen(explode(".",$gtime)[1]) == 2) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1]."0";
if(strlen(explode(".",$gtime)[1]) == 1) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1]."00"; if(strlen(explode(".",$gtime)[1]) == 1) return $hour.":".date("i:s",intval($gtime)).".".explode(".",$gtime)[1]."00";

View File

@ -2,6 +2,7 @@
class YTDownloader { class YTDownloader {
private $cache_dir; private $cache_dir;
private $cookie_dir; private $cookie_dir;
private $appSettings;
private $itag_info = array( private $itag_info = array(
// Full Video // Full Video
5 => "FLV[400x240]", 5 => "FLV[400x240]",
@ -81,6 +82,7 @@ private $itag_ext = array(
function __construct(){ function __construct(){
$this->cache_dir = dirname(__FILE__).'/.cache'; $this->cache_dir = dirname(__FILE__).'/.cache';
$this->cookie_dir = sys_get_temp_dir(); $this->cookie_dir = sys_get_temp_dir();
$this->appSettings = parse_ini_file('../config/config.ini',true);
if(!file_exists($this->cache_dir) && is_writeable(dirname(__FILE__))) { if(!file_exists($this->cache_dir) && is_writeable(dirname(__FILE__))) {
mkdir($this->cache_dir,0755); mkdir($this->cache_dir,0755);
} }
@ -89,6 +91,7 @@ public function getDownloadLinks($id) {
$returnData = FALSE; $returnData = FALSE;
$videoID = $this->extractId($id); $videoID = $this->extractId($id);
$webPage = $this->curlGet('https://www.youtube.com/watch?v='.$videoID); $webPage = $this->curlGet('https://www.youtube.com/watch?v='.$videoID);
if($webPage) {
$sts = null; $sts = null;
if(preg_match('|"sts":([0-9]{4,}),"|i', $webPage, $matches)) { if(preg_match('|"sts":([0-9]{4,}),"|i', $webPage, $matches)) {
$sts = $matches[1]; $sts = $matches[1];
@ -125,11 +128,11 @@ $thumbinfo = $playerData->storyboards->playerStoryboardSpecRenderer->spec;
$thumbparts = explode("|",$thumbinfo); $thumbparts = explode("|",$thumbinfo);
$thumbnum = count($thumbparts)-1; $thumbnum = count($thumbparts)-1;
$thumbdata = explode("#",$thumbparts[$thumbnum]); $thumbdata = explode("#",$thumbparts[$thumbnum]);
$vInfo['Title'] = $videoData['title']; $vInfo['Title'] = $playerData->videoDetails->title;
$vInfo['ChannelName'] = $videoData['author']; $vInfo['ChannelName'] = $playerData->videoDetails->author;
$vInfo['ChannelId'] = $videoData['ucid']; $vInfo['ChannelId'] = $playerData->videoDetails->channelId;
$vInfo['Thumbnail'] = $playerData->videoDetails->thumbnail->thumbnails[count($playerData->videoDetails->thumbnail->thumbnails)-1]->url; $vInfo['Thumbnail'] = $playerData->videoDetails->thumbnail->thumbnails[count($playerData->videoDetails->thumbnail->thumbnails)-1]->url;
$vInfo['Duration'] = $videoData['length_seconds']; $vInfo['Duration'] = $playerData->videoDetails->lengthSeconds;
$vInfo['Rating'] = $playerData->videoDetails->averageRating; $vInfo['Rating'] = $playerData->videoDetails->averageRating;
$vInfo['Captions'] = $captions; $vInfo['Captions'] = $captions;
$vInfo['Thumbs'] = array(); $vInfo['Thumbs'] = array();
@ -141,9 +144,9 @@ $vInfo['Thumbs']["fheight"] = $thumbdata[1];
$vInfo['Thumbs']["fcount"] = $thumbdata[2]; $vInfo['Thumbs']["fcount"] = $thumbdata[2];
$vInfo['Thumbs']["row"] = $thumbdata[3]; $vInfo['Thumbs']["row"] = $thumbdata[3];
} }
if (isset($videoData['url_encoded_fmt_stream_map']) && isset($videoData['adaptive_fmts'])) { if (isset($playerData->streamingData->formats) && isset($playerData->streamingData->adaptiveFormats)) {
$draft1 = explode(',',$videoData['url_encoded_fmt_stream_map']); $draft1 = $playerData->streamingData->formats;
$draft2 = explode(',',$videoData['adaptive_fmts']); $draft2 = $playerData->streamingData->adaptiveFormats;
foreach ($draft1 as $key) { foreach ($draft1 as $key) {
$draftLink[] = $key; $draftLink[] = $key;
} }
@ -151,7 +154,9 @@ foreach ($draft2 as $key) {
$draftLink[] = $key; $draftLink[] = $key;
} }
foreach($draftLink as $dlink) { foreach($draftLink as $dlink) {
parse_str($dlink,$mLink[]); if(isset($dlink->cipher)) parse_str($dlink->cipher,$mLink[]);
else $mLink[] = array("url"=>$dlink->url);
$mLink[count($mLink)-1]["itag"] = $dlink->itag;
} }
if (isset($mLink[0]['s'])) { if (isset($mLink[0]['s'])) {
$instructions = $this->get_instructions($webPage); $instructions = $this->get_instructions($webPage);
@ -159,37 +164,35 @@ $instructions = $this->get_instructions($webPage);
foreach($mLink as $linker) { foreach($mLink as $linker) {
if(isset($linker['s'])) { if(isset($linker['s'])) {
$linkData[] = array( $linkData[] = array(
'url' => preg_replace('@(https\:\/\/)[^\.]+(\.googlevideo\.com)@', 'https://redirector$2', $linker['url']).'&signature='.$this->sig_decipher($linker['s'], $instructions).'&title='.$this->clean_name($videoData['title']), 'url' => preg_replace('@(https\:\/\/)[^\.]+(\.googlevideo\.com)@', 'https://redirector$2', $linker['url']).'&'.$linker["sp"].'='.$this->sig_decode($linker['s'], $instructions).'&title='.$this->clean_name($playerData->videoDetails->title),
'itag' => $linker['itag'], 'itag' => $linker['itag'],
'type' => isset($this->itag_info[$linker['itag']]) ? $this->itag_info[$linker['itag']] : 'Unknown' 'type' => isset($this->itag_info[$linker['itag']]) ? $this->itag_info[$linker['itag']] : 'Unknown'
); );
} else { } else {
$linkData[] = array( $linkData[] = array(
'url' => preg_replace('@(https\:\/\/)[^\.]+(\.googlevideo\.com)@', 'https://redirector$2', $linker['url']).'&title='.$this->clean_name($videoData['title']), 'url' => preg_replace('@(https\:\/\/)[^\.]+(\.googlevideo\.com)@', 'https://redirector$2', $linker['url']).'&title='.$this->clean_name($playerData->videoDetails->title),
'itag' => $linker['itag'], 'itag' => $linker['itag'],
'type' => isset($this->itag_info[$linker['itag']]) ? $this->itag_info[$linker['itag']] : 'Unknown' 'type' => isset($this->itag_info[$linker['itag']]) ? $this->itag_info[$linker['itag']] : 'Unknown'
); );
} }
} }
} }
if (!empty($vInfo)) {
$returnData['info'] = $vInfo;
}if (!empty($linkData)) {
$returnData['dl'] = $linkData;
} }
if(!empty($vInfo)) $returnData['info'] = $vInfo;
if(!empty($linkData)) $returnData['dl'] = $linkData;
if(!$returnData && $this->appSettings["Media"]["youplay_fallback"]) $returnData = $this->appSettings["Media"]["invidious"];
return $returnData; return $returnData;
} }
protected function curlGet($url) { protected function curlGet($url) {
if(in_array('curl', get_loaded_extensions())){ if(in_array('curl', get_loaded_extensions())){
$appSettings = parse_ini_file('../config/config.ini',true);
$ch = curl_init($url); $ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0'); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HEADER, 0);
//curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); //curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
if($appSettings["Proxy"]["type"]) { if($this->appSettings["Proxy"]["type"]) {
curl_setopt($ch, CURLOPT_PROXY, $appSettings["Proxy"]["type"]."://".$appSettings["Proxy"]["domain"].":".$appSettings["Proxy"]["port"]); curl_setopt($ch, CURLOPT_PROXY, $this->appSettings["Proxy"]["type"]."://".$this->appSettings["Proxy"]["domain"].":".$this->appSettings["Proxy"]["port"]);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $appSettings["Proxy"]["username"].":".$appSettings["Proxy"]["password"]); curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->appSettings["Proxy"]["username"].":".$this->appSettings["Proxy"]["password"]);
} }
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
@ -219,11 +222,10 @@ if(file_exists($cache_player)) {
return unserialize(file_get_contents($cache_player)); return unserialize(file_get_contents($cache_player));
} else { } else {
$js_code = $this->curlGet($playerLink); $js_code = $this->curlGet($playerLink);
$instructions = $this->sig_js_decode($js_code); if($js_code){
if($instructions){
if(file_exists($this->cache_dir) && is_writeable($this->cache_dir)) if(file_exists($this->cache_dir) && is_writeable($this->cache_dir))
file_put_contents($cache_player, serialize($instructions)); file_put_contents($cache_player, serialize($js_code));
return $instructions; return $js_code;
} }
} }
} }
@ -238,63 +240,59 @@ $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename );
$filename = trim( $filename, '.-_' ); $filename = trim( $filename, '.-_' );
return $filename; return $filename;
} }
private function sig_decipher($signature, $instructions) { private function sig_decode($signature, $js_code) {
foreach($instructions as $opt){ $func_name = $this->parseFunctionName($js_code);
$instructions = (array)$this->parseFunctionCode($func_name, $js_code);
foreach($instructions as $opt) {
$command = $opt[0]; $command = $opt[0];
$value = $opt[1]; $value = $opt[1];
if($command == 'swap'){ if($command == 'swap') {
$temp = $signature[0]; $temp = $signature[0];
$signature[0] = $signature[$value % strlen($signature)]; $signature[0] = $signature[$value % strlen($signature)];
$signature[$value] = $temp; $signature[$value] = $temp;
} elseif($command == 'splice'){ } elseif ($command == 'splice') {
$signature = substr($signature, $value); $signature = substr($signature, $value);
} elseif($command == 'reverse'){ } elseif ($command == 'reverse') {
$signature = strrev($signature); $signature = strrev($signature);
} }
} }
return trim($signature); return trim($signature);
} }
private function sig_js_decode($file){ private function parseFunctionName($js_code) {
$script = $this->getBetween($file, 'a=a.split("");', ';return a.join("")'); if (preg_match('@,\s*encodeURIComponent\((\w{2})@is', $js_code, $matches)) {
$script = str_replace(array("a,","\n"), array(',',''), $script); $func_name = $matches[1];
$script2= $this->getBetween($file, 'var ' . substr($script, 0, 2).'={', '};'); $func_name = preg_quote($func_name);
$script2= str_replace('a,b', 'a', $script2); return $func_name;
$script = str_replace(substr($script, 0, 2).'.', '', $script);
$script = str_replace('(', '', $script);
$script = str_replace(')', '', $script);
$script_ex= explode(";", $script);
$script2_ex = explode("\n", $script2);
for($i = 0; $i < count($script2_ex); $i++) {
$tmp = isset($script2_ex[$i]) ? explode(':', $script2_ex[$i]) : [];
$n = isset($tmp[0]) ? $tmp[0] : '';
$m = isset($tmp[1]) ? $tmp[1] : '';
$tempS[$n] = $m;
} }
for($i = 0; $i < count($script_ex); $i++) { else if (preg_match('@\b([a-zA-Z0-9$]{2})\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)@is', $js_code, $matches)) {
$tmp = isset($script_ex[$i]) ? explode(',', $script_ex[$i]) : []; return preg_quote($matches[1]);
$a = isset($tmp[0]) ? $tmp[0] : '';
$b = isset($tmp[1]) ? $tmp[1] : '';
$deKey[] = $this->createCommad($a, $b, $tempS);
} }
return $deKey; return null;
} }
private function createCommad($value, $num, $source) { private function parseFunctionCode($func_name, $player_htmlz) {
$result = ''; if (preg_match('/' . $func_name . '=function\([a-z]+\){(.*?)}/', $player_htmlz, $matches)) {
if (isset($source[$value]) && mb_strpos($source[$value], 'reverse')) { $js_code = $matches[1];
$result = array('reverse', ''); if (preg_match_all('/([a-z0-9]{2})\.([a-z0-9]{2})\([^,]+,(\d+)\)/i', $js_code, $matches) != false) {
} elseif (isset($source[$value]) && mb_strpos($source[$value], 'a.splice')) { $obj_list = $matches[1];
$result = array('splice', $num); $func_list = $matches[2];
} else { preg_match_all('/(' . implode('|', $func_list) . '):function(.*?)\}/m', $player_htmlz, $matches2, PREG_SET_ORDER);
$result = array('swap', $num); $functions = array();
} foreach ($matches2 as $m) {
return $result; if (strpos($m[2], 'splice') !== false) {
} $functions[$m[1]] = 'splice';
private function getBetween($content, $start, $end) { } elseif (strpos($m[2], 'a.length') !== false) {
$r = explode($start, $content); $functions[$m[1]] = 'swap';
if (isset($r[1])) { } elseif (strpos($m[2], 'reverse') !== false) {
$r = explode($end, $r[1]); $functions[$m[1]] = 'reverse';
return $r[0]; }
} }
return ''; $instructions = array();
foreach ($matches[2] as $index => $name) {
$instructions[] = array($functions[$name], $matches[3][$index]);
}
return $instructions;
}
}
return null;
} }
} }

View File

@ -104,6 +104,34 @@ echo "<option value='".$languages[$i]."'".$selected.">"._('Language_'.$languages
</a> </a>
</div> </div>
<div style="float:left;width:50%;text-align:right;margin-top:16px"> <div style="float:left;width:50%;text-align:right;margin-top:16px">
<h3><?=_('Rewrite Instagram to Bibliogram at compose')?></h3>
</div>
<div class="rewrite_bibliogram_wrap" style="float:left;width:50%">
<div class="switch" style="float:left">
<input type="checkbox" id="setting_rewrite_bibliogram">
<div class="switch-btn">
<span></span>
</div>
</div>
<a href="javascript:void(0)" id="setting_rewrite_bibliogram_reset" style="float:left;display:none">
<i class="fa fa-2x fa-times" style="margin-top:8px"></i>
</a>
</div>
<div style="float:left;width:50%;text-align:right;margin-top:16px">
<h3><?=_('Rewrite Facebook to NoFB at compose')?></h3>
</div>
<div class="rewrite_nofb_wrap" style="float:left;width:50%">
<div class="switch" style="float:left">
<input type="checkbox" id="setting_rewrite_nofb">
<div class="switch-btn">
<span></span>
</div>
</div>
<a href="javascript:void(0)" id="setting_rewrite_nofb_reset" style="float:left;display:none">
<i class="fa fa-2x fa-times" style="margin-top:8px"></i>
</a>
</div>
<div style="float:left;width:50%;text-align:right;margin-top:16px">
<h3><?=_('Local instance')?></h3> <h3><?=_('Local instance')?></h3>
</div> </div>
<div class="local_instance_wrap" style="float:left;width:50%"> <div class="local_instance_wrap" style="float:left;width:50%">

View File

@ -122,6 +122,34 @@
<i class="fa fa-2x fa-times" style="margin-top:8px"></i> <i class="fa fa-2x fa-times" style="margin-top:8px"></i>
</a> </a>
</div> </div>
<div style="float:left;width:50%;text-align:right;margin-top:16px">
<h3><?=_('Redirect Instagram to Bibliogram')?></h3>
</div>
<div class="redirect_bibliogram_wrap" style="float:left;width:50%">
<div class="switch" style="float:left">
<input type="checkbox" id="setting_redirect_bibliogram">
<div class="switch-btn">
<span></span>
</div>
</div>
<a href="javascript:void(0)" id="setting_redirect_bibliogram_reset" style="float:left;display:none">
<i class="fa fa-2x fa-times" style="margin-top:8px"></i>
</a>
</div>
<div style="float:left;width:50%;text-align:right;margin-top:16px">
<h3><?=_('Redirect Facebook to NoFB')?></h3>
</div>
<div class="redirect_nofb_wrap" style="float:left;width:50%">
<div class="switch" style="float:left">
<input type="checkbox" id="setting_redirect_nofb">
<div class="switch-btn">
<span></span>
</div>
</div>
<a href="javascript:void(0)" id="setting_redirect_nofb_reset" style="float:left;display:none">
<i class="fa fa-2x fa-times" style="margin-top:8px"></i>
</a>
</div>
<span style="visibility:hidden">-</span> <span style="visibility:hidden">-</span>
</div> </div>
</article> </article>

View File

@ -1 +1 @@
2.4.6 2.4.7

View File

@ -0,0 +1,24 @@
<div class="overlay_simple overlay_redirect_bibliogram invisible">
<header class="overlay_simple_header">
<span><?=_('Protect your privacy!')?></span>
</header>
<div class="overlay_simple_body">
<div class="overlay_redirect_bibliogram_text" style="margin-bottom:10px">
<?=_("Halcyon has detected that you're trying to click a link to the centralized photo platform Instagram. Halcyon can automatically redirect that link to Bibliogram, a privacy-friendly and faster way to view this content for free and without any ads. Do you want to use Bibliogram?")?><br/>
<center><a href="https://github.com/cloudrac3r/bibliogram" class="halcyon_link" target="_blank"><?=_("Tell me more about Bibliogram!")?></a></center>
<div style="margin-bottom:20px;width:100%">
<div class="switch" style="margin:0;float:left">
<input type="checkbox" id="redirect_bibliogram_permanent">
<div class="switch-btn">
<span></span>
</div>
</div>
<label for="redirect_bibliogram_permanent" style="margin-left:5px;vertical-align:sub"><?=_('Remember my decision')?></label>
</div>
</div>
<div class="overlay_simple_controls">
<button class="overlay_redirect_bibliogram_yes toot_button" style="float:right;width:150px"><div class="toot_button_label"><i class="fa fa-fw fa-check"></i><span><?=_('Open Bibliogram')?></span></div></button>
<a href="javascript:void(0)" class="overlay_redirect_bibliogram_no halcyon_link" style="float:right;margin-top:5px;margin-right:10px"><i class="fa fa-times"></i> <?=_('No, thanks')?></a>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
<div class="overlay_simple overlay_redirect_nofb invisible">
<header class="overlay_simple_header">
<span><?=_('Protect your privacy!')?></span>
</header>
<div class="overlay_simple_body">
<div class="overlay_redirect_nofb_text" style="margin-bottom:10px">
<?=_("Halcyon has detected that you're trying to click a link to the centralized platform Facebook. Halcyon can automatically redirect that link to NoFB, a privacy-friendly and faster way to view this content for free and without any ads. Do you want to use NoFB?")?><br/>
<center><a href="https://nofb.pw" class="halcyon_link" target="_blank"><?=_("Tell me more about NoFB!")?></a></center>
<div style="margin-bottom:20px;width:100%">
<div class="switch" style="margin:0;float:left">
<input type="checkbox" id="redirect_nofb_permanent">
<div class="switch-btn">
<span></span>
</div>
</div>
<label for="redirect_nofb_permanent" style="margin-left:5px;vertical-align:sub"><?=_('Remember my decision')?></label>
</div>
</div>
<div class="overlay_simple_controls">
<button class="overlay_redirect_nofb_yes toot_button" style="float:right;width:150px"><div class="toot_button_label"><i class="fa fa-fw fa-check"></i><span><?=_('Open NoFB')?></span></div></button>
<a href="javascript:void(0)" class="overlay_redirect_nofb_no halcyon_link" style="float:right;margin-top:5px;margin-right:10px"><i class="fa fa-times"></i> <?=_('No, thanks')?></a>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
<div class="overlay_simple overlay_rewrite_bibliogram invisible">
<header class="overlay_simple_header">
<span><?=_('Protect your privacy!')?></span>
</header>
<div class="overlay_simple_body">
<div class="overlay_rewrite_bibliogram_text" style="margin-bottom:10px">
<?=_("Halcyon has detected that you're trying to post a link to the centralized photo platform Bibliogram. Halcyon can automatically rewrite that link to Bibliogram, a privacy-friendly and faster way to view this content for free and without any ads. Do you want to replace your link with Bibliogram?")?><br/>
<center><a href="https://github.com/cloudrac3r/bibliogram" class="halcyon_link" target="_blank"><?=_("Tell me more about Bibliogram!")?></a></center>
<div style="margin-bottom:20px;width:100%">
<div class="switch" style="margin:0;float:left">
<input type="checkbox" id="rewrite_bibliogram_permanent">
<div class="switch-btn">
<span></span>
</div>
</div>
<label for="redirect_bibliogram_permanent" style="margin-left:5px;vertical-align:sub"><?=_('Remember my decision')?></label>
</div>
</div>
<div class="overlay_simple_controls">
<button class="overlay_rewrite_bibliogram_yes toot_button" style="float:right;width:180px"><div class="toot_button_label"><i class="fa fa-fw fa-check"></i><span><?=_('Rewrite to Bibliogram')?></span></div></button>
<a href="javascript:void(0)" class="overlay_rewrite_bibliogram_no halcyon_link" style="float:right;margin-top:5px;margin-right:10px"><i class="fa fa-times"></i> <?=_('No, thanks')?></a>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
<div class="overlay_simple overlay_rewrite_nofb invisible">
<header class="overlay_simple_header">
<span><?=_('Protect your privacy!')?></span>
</header>
<div class="overlay_simple_body">
<div class="overlay_rewrite_nofb_text" style="margin-bottom:10px">
<?=_("Halcyon has detected that you're trying to post a link to the centralized platform Facebook. Halcyon can automatically rewrite that link to NoFB, a privacy-friendly and faster way to view this content for free and without any ads. Do you want to replace your link with NoFB?")?><br/>
<center><a href="https://nofb.pw" class="halcyon_link" target="_blank"><?=_("Tell me more about NoFB!")?></a></center>
<div style="margin-bottom:20px;width:100%">
<div class="switch" style="margin:0;float:left">
<input type="checkbox" id="rewrite_nofb_permanent">
<div class="switch-btn">
<span></span>
</div>
</div>
<label for="redirect_nofb_permanent" style="margin-left:5px;vertical-align:sub"><?=_('Remember my decision')?></label>
</div>
</div>
<div class="overlay_simple_controls">
<button class="overlay_rewrite_nofb_yes toot_button" style="float:right;width:150px"><div class="toot_button_label"><i class="fa fa-fw fa-check"></i><span><?=_('Rewrite to NoFB')?></span></div></button>
<a href="javascript:void(0)" class="overlay_rewrite_nofb_no halcyon_link" style="float:right;margin-top:5px;margin-right:10px"><i class="fa fa-times"></i> <?=_('No, thanks')?></a>
</div>
</div>
</div>