1
0
mirror of https://notabug.org/halcyon-suite/halcyon synced 2024-12-10 00:45:21 +01:00

Many bugfixes,add trending hashtags,add URL unshortener,redirect YouTube to Invidious,translation improvements,add Spanish translation

This commit is contained in:
nipos 2019-08-21 18:25:27 +02:00
parent 3b87814f98
commit 045d6f74c5
37 changed files with 2113 additions and 122 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
## Blog
- Release of Version 2.4.2 - Many bugfixes,add trending hashtags,add URL unshortener,redirect YouTube to Invidious,translation improvements,add Spanish translation
- Release of Version 2.4.1 - Improve French and German translation,respect Pleromas/GlitchSocs custom poll limits,add extension download link,many bugfixes
- We published the new Halcyon Share Extension at [Firefox Addons](https://addons.mozilla.org/en-US/firefox/addon/halcyon-share/) and [NotABug](https://notabug.org/halcyon-suite/halcyon-share)
- Release of Version 2.4.0 - Share links to Halcyon,preview overlays for mentions and more (blog article coming soon)

View File

@ -579,10 +579,10 @@ font-weight: 300;
.single_reply_status .status_preview,.report_status .status_preview {
border-top: 1px solid #E1E8ED;
}
.single_reply_status .status_preview .toot_entry .toot_footer,.report_stauts .status_preview .toot_entry .toot_footer {
.single_reply_status .status_preview .toot_entry .toot_footer,.report_status .status_preview .toot_entry .toot_footer {
display: none!important;
}
.single_reply_status .status_preview .toot_entry .link_preview,.report_stauts .status_preview .toot_entry .link_preview {
.single_reply_status .status_preview .toot_entry .link_preview,.report_status .status_preview .toot_entry .link_preview {
display: none!important;
}
.single_reply_status .status_form .status_bottom,.report_status .status_form .status_bottom {
@ -975,6 +975,9 @@ position: relative;
box-sizing: border-box;
border: 1px solid #DCDFE1;
}
.media_views.link_preview {
cursor:pointer;
}
.media_views.media_full_height {
height:auto;
}
@ -1517,9 +1520,12 @@ overflow: hidden;
margin-right: 8px;
border-radius: 5px;
}
.account_box .label_box {
.what_to_follow .account_box .label_box {
width: 200px;
}
.trending_hashtags .account_box .label_box {
width:100%;
}
.account_box .label_box h3 {
overflow: hidden;
white-space: nowrap;

View File

@ -59,7 +59,7 @@ di[re[4]] = re[3];
}
return di;
}
function replaceInternalLink(){
function replaceInternalLink() {
$(".toot_article a,.profile_bio a,.follows_profile_bio a").each(function(i) {
const pltags = $(this).attr('href').match(/https?:\/\/.+..+\/tag\/([a-zA-Z\d_%]+)\/?$/);
if(pltags) $(this).attr('target','_self').attr('href','/search?q='+pltags[1]);
@ -77,6 +77,24 @@ const gsstatus = $(this).attr('href').match(/https?:\/\/.+..+\/notice\/(\d+)\/?$
if(gsstatus) $(this).attr('target','_self').attr('href',"javascript:openStatus('"+gsstatus[0]+"');void(0)");
const plstatus = $(this).attr('href').match(/https?:\/\/.+..+\/objects\/([\da-z]{8}-[\da-z]{4}-[\da-z]{4}-[\da-z]{4}-[\da-z]{12})\/?$/);
if(plstatus) $(this).attr('target','_self').attr('href',"javascript:openStatus('"+plstatus[0]+"');void(0)");
const ytcom = $(this).attr('href').match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/);
if(ytcom) $(this).attr('target','_self').attr('href',"javascript:openVideo('"+ytcom[2]+"');void(0)");
const ytbe = $(this).attr('href').match(/https?:\/\/(www\.)?youtu\.be\/([a-zA-Z\d_-]+)/);
if(ytbe) $(this).attr('target','_self').attr('href',"javascript:openVideo('"+ytbe[2]+"');void(0)");
if(server_setting_unshorten && checkURLshortener($(this).attr('href'))) {
var linkrand = Math.round(Math.random()*1000000);
$(this).attr("data-random",linkrand);
$.ajax("/unshorten.php?url="+encodeURIComponent($(this).attr('href'))).done(function(data) {
$(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").attr("href",data);
$(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").children().eq(1).text(data.split("//")[0]);
link = data.replace("https://","");
link = link.replace("http://","");
if(link.length > 30) $(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").children().eq(1).addClass("ellipsis");
else $(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").children().eq(1).removeClass("ellipsis");
$(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").children().eq(1).text(link.substr(0,30));
$(".toot_article a,.profile_bio a,.follows_profile_bio a").filter("[data-random="+linkrand+"]").children().eq(2).text(link.substr(30));
});
}
});
$(".toot_article a").each(function(i) {
const ytcom = $(this).attr('href').match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z\d_-]+)/);
@ -169,7 +187,6 @@ current_filters = new Array;
}
localStorage.setItem("current_display_name",AccountObj["display_name"]);
localStorage.setItem("current_acct",AccountObj["acct"]);
localStorage.setItem("current_url","/@"+AccountObj["acct"]+"@"+current_instance+"?mid="+current_id);
localStorage.setItem("current_header",AccountObj["header"]);
localStorage.setItem("current_avatar",AccountObj["avatar"]);
localStorage.setItem("current_locked",AccountObj["locked"]);
@ -179,7 +196,6 @@ localStorage.setItem("current_followers_count",AccountObj["followers_count"]);
localStorage.setItem("current_follow_loaded","false");
current_display_name = localStorage.getItem("current_display_name");
current_acct = localStorage.getItem("current_acct");
current_url = localStorage.getItem("current_url");
current_header = localStorage.getItem("current_header");
current_avatar = localStorage.getItem("current_avatar");
current_locked = localStorage.getItem("current_locked");
@ -263,7 +279,6 @@ api_user_token: authtoken
});
current_display_name = localStorage.getItem("current_display_name");
current_acct = localStorage.getItem("current_acct");
current_url = localStorage.getItem("current_url");
current_header = localStorage.getItem("current_header");
current_avatar = localStorage.getItem("current_avatar");
current_locked = localStorage.getItem("current_locked");
@ -287,15 +302,15 @@ is_account_locked = " <i class='fa fa-lock'></i>";
}
$(".js_current_profile_displayname").html(current_display_name);
$(".js_current_profile_username").html(current_acct+is_account_locked);
$(".js_current_profile_link").attr("href", current_url);
$(".js_current_profile_link").attr("href","/@"+current_acct+"@"+current_instance+"?mid="+current_id);
$(".js_current_header_image").attr("src", current_header);
$(".js_current_profile_image").attr("src", current_avatar);
$(".js_current_toots_count").text(current_statuses_count);
$(".js_current_following_count").text(current_following_count);
$(".js_current_followers_count").text(current_followers_count);
$(".current_toots_count_link").attr("href",current_url);
$(".current_following_count_link").attr("href",current_url);
$(".current_followers_count_link").attr("href",current_url);
$(".current_toots_count_link").attr("href","/@"+current_acct+"@"+current_instance+"?mid="+current_id);
$(".current_following_count_link").attr("href","/@"+current_acct+"@"+current_instance+"/following?mid="+current_id);
$(".current_followers_count_link").attr("href","/@"+current_acct+"@"+current_instance+"/followers?mid="+current_id);
if($(window).width() < 1200) {
responsive_design = true;
$(".left_column").append($("<div>").attr("class","responsive_left").append($(".right_column").children()));
@ -317,6 +332,7 @@ localStorage.setItem("setting_desktop_notifications","false");
if(localStorage.setting_who_to_follow == "true") {
setWhoToFollow();
}
setTrendingHashtags();
if(!localStorage.hide_firefox_download || localStorage.hide_firefox_download != "true") $("#widget_ffdl").show();
replace_emoji();
}
@ -418,6 +434,33 @@ $('.what_to_follow_'+id+' .label_box > .follow_button').attr('data',search.accou
follow_loaded++;
});
}
function setTrendingHashtags() {
api.get("trends",function(data) {
if(data.length == 0) $("#trends_icon").removeClass("fa-circle-o-notch").removeClass("fa-spin").addClass("fa-hashtag").addClass("fa-stack-1x").after($("<i>").addClass("fa").addClass("fa-ban").addClass("fa-stack-2x"));
else {
for(var i=0;i<5;i++) {
if(i < data.length) {
var ht_toots = 0;
var ht_users = 0;
for(var a=0;a<data[i].history.length;a++) {
ht_toots += parseInt(data[i].history[a].uses);
ht_users += parseInt(data[i].history[a].accounts);
}
$(".trending_hashtags .trending_"+i+" a").attr("href","/search?q="+data[i].name);
$(".trending_hashtags .trending_"+i+" .dn").text("#"+data[i].name);
$(".trending_hashtags .trending_"+i+" .un").text(ht_toots+" "+__("toots by")+" "+ht_users+" "+__("users"));
}
else {
$(".trending_hashtags .trending_"+i).remove();
}
}
$(".trends_loading").hide();
$(".trending_hashtags").show();
}
},function() {
$("#trends_icon").removeClass("fa-circle-o-notch").removeClass("fa-spin").addClass("fa-hashtag").addClass("fa-stack-1x").after($("<i>").addClass("fa").addClass("fa-ban").addClass("fa-stack-2x"));
});
}
function checkEmojiSupport() {
var ctx = document.createElement("canvas").getContext("2d");
ctx.fillText("😗",-2,4);
@ -437,6 +480,17 @@ window.location.href = "/404";
}
});
}
function openVideo(video) {
if(localStorage.setting_redirect_invidious == "true") window.open("https://"+server_setting_invidious+"/watch?v="+video,"_blank");
else if(localStorage.setting_redirect_invidious == "false") window.open("https://www.youtube.com/watch?v="+video,"_blank");
else {
$("#js-overlay_content_wrap .temporary_object").empty();
$('#js-overlay_content_wrap').addClass('view');
$('#js-overlay_content_wrap').addClass('black_08');
$('.overlay_redirect_invidious').data("video",video);
$('.overlay_redirect_invidious').removeClass('invisible');
}
}
function embedMedia(source,element,watchid) {
if(element.children(".media_views").length == 0) {
let media_views = `<div class='media_views' sid="${element.parent().parent().parent().attr("sid")}" media_length='1' style="border:0;border-radius:0">`;
@ -449,7 +503,7 @@ media_views += (`
else if( source == "youtube" && localStorage.setting_play_invidious == "true") {
media_views += (`
<div class="media_attachment" otype="video/gifv" mediacount="0">
<iframe src="https://www.invidio.us/embed/${watchid}" frameborder="0" allowfullscreen></iframe>
<iframe src="https://${server_setting_invidious}/embed/${watchid}" frameborder="0" allowfullscreen></iframe>
</div>`);
}
else if(source == "vimeo" && server_setting_vimeo == true && localStorage.setting_play_vimeo == "true") {
@ -495,3 +549,21 @@ submitStatusArray(nparams,callback);
}
});
}
function checkURLshortener(link) {
var short = true;
if(link.indexOf("https://") != -1 || link.indexOf("http://") != -1) {
if(link.indexOf("://www.") != -1) short = false;
link = link.replace("https://","");
link = link.replace("http://","");
var short_handle = link.split("/");
var domain = link.split(".");
if(domain.length == 2) var sld = domain[0];
else var sld = domain[1];
if(sld.length < 1 || sld.length > 7) short = false;
if(short_handle.length != 2) short = false;
else if(!short_handle[1].match(/^[a-zA-Z0-9_-]+$/)) short = false;
else if(short_handle[1].length > 10) short = false;
}
else short = false;
return short;
}

View File

@ -443,6 +443,12 @@ $("#setting_play_invidious")[0].checked = true;
if(localStorage.setting_play_vimeo == "true" && $("#setting_play_vimeo").length == 1) {
$("#setting_play_vimeo")[0].checked = true;
}
if(localStorage.setting_redirect_invidious == "true") {
$("#setting_redirect_invidious")[0].checked = true;
}
if(localStorage.setting_redirect_invidious != "unset") {
$("#setting_redirect_invidious_reset").show();
}
});
$("#setting_play_gif").change(function() {
if(this.checked) {
@ -514,6 +520,23 @@ localStorage.setItem("setting_play_vimeo","false");
putMessage(__("Vimeo embeds disabled"));
}
});
$("#setting_redirect_invidious").change(function() {
$("#setting_redirect_invidious_reset").fadeIn();
if(this.checked) {
localStorage.setItem("setting_redirect_invidious","true");
putMessage(__("YouTube links redirected to Invidious"));
}
else {
localStorage.setItem("setting_redirect_invidious","false");
putMessage(__("Youtube links not redirected anymore"));
}
});
$("#setting_redirect_invidious_reset").click(function() {
localStorage.setItem("setting_redirect_invidious","unset");
$("#setting_redirect_invidious_reset").fadeOut();
$("#setting_redirect_invidious")[0].checked = false;
putMessage(__("Youtube link redirect reset to default"));
});
}
else if(window.location.pathname == "/settings/blocks") {
$('#js-settings_nav_blocks').toggleClass('view');

View File

@ -87,7 +87,7 @@ media_views += "</div>";
media_views += "</div>";
var media_view = $("<div>");
media_view.append(media_views);
if(status.sensitive) media_view.find(".media_attachment").addClass("sensitive");
if(status.sensitive && localStorage.setting_show_nsfw == "false") media_view.find(".media_attachment").addClass("sensitive");
for(let i in audio_embeds) {
media_view.append(audio_embeds[i]);
}
@ -103,11 +103,21 @@ const htbe = card.url.match(/https?:\/\/(www\.)?hooktube\.com\/([a-zA-Z\d_-]+)/)
const vimeo = card.url.match(/https?:\/\/(www\.)?vimeo\.com\/([\d]+)/);
const peertube = card.url.match(/https?:\/\/.+..+\/videos\/watch\/([\da-z]{8}-[\da-z]{4}-[\da-z]{4}-[\da-z]{4}-[\da-z]{12})\/?$/);
if(((!ytcom && !htcom && !ivcom && !ytbe && !htbe) || (localStorage.setting_play_youplay == "false" && localStorage.setting_play_invidious == "false")) && (!vimeo || localStorage.setting_play_vimeo) && (!peertube || localStorage.setting_play_peertube)) {
let preview_html = (`<div class="media_views link_preview" media_length="1" style="height:unset" data-url="${card.url}">
var randattr = "";
if(server_setting_unshorten && checkURLshortener(card.url)) {
var linkrand = Math.round(Math.random()*1000000);
randattr = ' data-random="'+linkrand+'"';
$(this).attr("data-random",linkrand);
$.ajax("/unshorten.php?url="+encodeURIComponent(card.url)).done(function(data) {
$(".media_views.link_preview").filter("[data-random="+linkrand+"]").data("url",data);
$(".media_views.link_preview").filter("[data-random="+linkrand+"]").find(".card_link").text(data);
});
}
let preview_html = (`<div class="media_views link_preview" media_length="1" style="height:unset" data-url="${card.url}"${randattr}>
<img src="${card.image}" style="width:${card.width};max-width:200px;float:left;margin-right:5px">
<strong>${card.title}</strong><br/>
<span>${card.description}</span><br/>
<span style="color:#777777">${card.url}</span>`);
<span style="color:#777777" class="card_link">${card.url}</span>`);
return preview_html;
}
else return "";
@ -175,12 +185,16 @@ for(var i=0;i<status.mentions.length;i++) {
if(status.mentions[i].acct.indexOf("@") == -1) status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'@'+current_instance+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
else status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
}
if(!status.mentions.find(function(account) {
return account.id == this;
},status.account.id)) {
var writtenby = new Object();
writtenby.id = status.account.id;
writtenby.username = status.account.username;
writtenby.url = status.account.url;
writtenby.acct = status.account.acct;
status.mentions.push(writtenby);
}
var status_account_link;
if(status.account.acct.indexOf("@") == -1) status_account_link = "/@"+status.account.acct+"@"+current_instance+"?mid="+status.account.id;
else status_account_link = "/@"+status.account.acct+"?mid="+status.account.id;
@ -305,7 +319,7 @@ ${preview_object}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}" content_warning="${htmlEscape(status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -345,12 +359,16 @@ for(var i=0;i<status.reblog.mentions.length;i++) {
if(status.reblog.mentions[i].acct.indexOf("@") == -1) status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'@'+current_instance+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
else status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
}
if(!status.reblog.mentions.find(function(account) {
return account.id == this;
},status.reblog.account.id)) {
var writtenby = new Object();
writtenby.id = status.reblog.account.id;
writtenby.username = status.reblog.account.username;
writtenby.url = status.reblog.account.url;
writtenby.acct = status.reblog.account.acct;
status.reblog.mentions.push(writtenby);
}
const status_datetime= getRelativeDatetime(Date.now(), getConversionedDate(null, status.reblog.created_at)),
status_attr_datetime = getConversionedDate(null, status.reblog.created_at);
var status_reblog_account_link,status_account_link;
@ -470,7 +488,7 @@ ${preview_object}
</article>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}" content_warning="${htmlEscape(status.reblog.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -513,12 +531,16 @@ for(var i=0;i<status.mentions.length;i++) {
if(status.mentions[i].acct.indexOf("@") == -1) status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'@'+current_instance+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
else status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
}
if(!status.mentions.find(function(account) {
return account.id == this;
},status.account.id)) {
var writtenby = new Object();
writtenby.id = status.account.id;
writtenby.username = status.account.username;
writtenby.url = status.account.url;
writtenby.acct = status.account.acct;
status.mentions.push(writtenby);
}
var status_account_link;
if(status.account.acct.indexOf("@") == -1) status_account_link = "/@"+status.account.acct+"@"+current_instance+"?mid="+status.account.id;
else status_account_link = "/@"+status.account.acct+"?mid="+status.account.id;
@ -626,7 +648,7 @@ ${preview_object}
</article>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}" content_warning="${htmlEscape(status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -800,12 +822,16 @@ for(var i=0;i<NotificationObj.status.mentions.length;i++) {
if(NotificationObj.status.mentions[i].acct.indexOf("@") == -1) NotificationObj.status.content = NotificationObj.status.content.replace(new RegExp('href="'+NotificationObj.status.mentions[i].url+'"',"g"),'href="/@'+NotificationObj.status.mentions[i].acct+'@'+current_instance+'?mid='+NotificationObj.status.mentions[i].id+'" data-mid="'+NotificationObj.status.mentions[i].id+'"');
else NotificationObj.status.content = NotificationObj.status.content.replace(new RegExp('href="'+NotificationObj.status.mentions[i].url+'"',"g"),'href="/@'+NotificationObj.status.mentions[i].acct+'?mid='+NotificationObj.status.mentions[i].id+'" data-mid="'+NotificationObj.status.mentions[i].id+'"');
}
if(!NotificationObj.status.mentions.find(function(account) {
return account.id == this;
},NotificationObj.status.account.id)) {
var writtenby = new Object();
writtenby.id = NotificationObj.status.account.id;
writtenby.username = NotificationObj.status.account.username;
writtenby.url = NotificationObj.status.account.url;
writtenby.acct = NotificationObj.status.account.acct;
NotificationObj.status.mentions.push(writtenby);
}
if(NotificationObj.status.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+NotificationObj.status.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -917,7 +943,7 @@ ${preview_object}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${NotificationObj.status.id}" mentions='${JSON.stringify(NotificationObj.status.mentions)}' display_name="${NotificationObj.account.display_name}" privacy="${NotificationObj.status.visibility}">
<button class="reply_button" tid="${NotificationObj.status.id}" mentions='${JSON.stringify(NotificationObj.status.mentions)}' display_name="${NotificationObj.account.display_name}" privacy="${NotificationObj.status.visibility}" content_warning="${htmlEscape(NotificationObj.status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -966,12 +992,16 @@ for(var i=0;i<NotificationObj.status.mentions.length;i++) {
if(NotificationObj.status.mentions[i].acct.indexOf("@") == -1) NotificationObj.status.content = NotificationObj.status.content.replace(new RegExp('href="'+NotificationObj.status.mentions[i].url+'"',"g"),'href="/@'+NotificationObj.status.mentions[i].acct+'@'+current_instance+'?mid='+NotificationObj.status.mentions[i].id+'" data-mid="'+NotificationObj.status.mentions[i].id+'"');
else NotificationObj.status.content = NotificationObj.status.content.replace(new RegExp('href="'+NotificationObj.status.mentions[i].url+'"',"g"),'href="/@'+NotificationObj.status.mentions[i].acct+'?mid='+NotificationObj.status.mentions[i].id+'" data-mid="'+NotificationObj.status.mentions[i].id+'"');
}
if(!NotificationObj.status.mentions.find(function(account) {
return account.id == this;
},NotificationObj.status.account.id)) {
var writtenby = new Object();
writtenby.id = NotificationObj.status.account.id;
writtenby.username = NotificationObj.status.account.username;
writtenby.url = NotificationObj.status.account.url;
writtenby.acct = NotificationObj.status.account.acct;
NotificationObj.status.mentions.push(writtenby);
}
if(NotificationObj.status.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+NotificationObj.status.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -1089,7 +1119,7 @@ ${preview_object}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${NotificationObj.status.id}" mentions='${JSON.stringify(NotificationObj.status.mentions)}' display_name="${NotificationObj.account.display_name}" privacy="${NotificationObj.status.visibility}">
<button class="reply_button" tid="${NotificationObj.status.id}" mentions='${JSON.stringify(NotificationObj.status.mentions)}' display_name="${NotificationObj.account.display_name}" privacy="${NotificationObj.status.visibility}" content_warning="${htmlEscape(NotificationObj.status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -1202,12 +1232,16 @@ for(var i=0;i<status.mentions.length;i++) {
if(status.mentions[i].acct.indexOf("@") == -1) status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'@'+current_instance+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
else status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
}
if(!status.mentions.find(function(account) {
return account.id == this;
},status.account.id)) {
var writtenby = new Object();
writtenby.id = status.account.id;
writtenby.username = status.account.username;
writtenby.url = status.account.url;
writtenby.acct = status.account.acct;
status.mentions.push(writtenby);
}
if(status.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+status.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -1320,7 +1354,7 @@ ${preview_object}
</section>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}" content_warning="${htmlEscape(status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -1345,7 +1379,7 @@ ${toot_reblog_button}
<img class="js_current_profile_image" src="${current_avatar}">
</div>
<div class="status_top">
<input class="status_spoiler invisible" name="status_spoiler" placeholder="${__('Content warning')}" data-random="${Math.round(Math.random()*1000)}" type="text"/>
<input class="status_spoiler invisible" name="status_spoiler" placeholder="${__('Content warning')}" value="${htmlEscape(status.spoiler_text)}" data-random="${Math.round(Math.random()*1000)}" type="text"/>
</div>
<div class="status_main">
<!-- text area -->
@ -1471,12 +1505,16 @@ for(var i=0;i<status.reblog.mentions.length;i++) {
if(status.reblog.mentions[i].acct.indexOf("@") == -1) status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'@'+current_instance+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
else status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
}
if(!status.reblog.mentions.find(function(account) {
return account.id == this;
},status.reblog.account.id)) {
var writtenby = new Object();
writtenby.id = status.reblog.account.id;
writtenby.username = status.reblog.account.username;
writtenby.url = status.reblog.account.url;
writtenby.acct = status.reblog.account.acct;
status.reblog.mentions.push(writtenby);
}
if(status.reblog.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+status.reblog.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -1575,7 +1613,7 @@ ${preview_object}
</section>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}" content_warning="${htmlEscape(status.reblog.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -1605,7 +1643,7 @@ ${preview_object}
<img class="js_current_profile_image" src="${current_avatar}">
</div>
<div class="status_top">
<input class="status_spoiler invisible" name="status_spoiler" placeholder="${__('Content warning')}" data-random="${Math.round(Math.random()*1000)}" type="text"/>
<input class="status_spoiler invisible" name="status_spoiler" placeholder="${__('Content warning')}" value="${htmlEscape(status.reblog.spoiler_text)}" data-random="${Math.round(Math.random()*1000)}" type="text"/>
</div>
<div class="status_main">
<!-- text area -->
@ -1766,12 +1804,16 @@ for(var i=0;i<status.mentions.length;i++) {
if(status.mentions[i].acct.indexOf("@") == -1) status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'@'+current_instance+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
else status.content = status.content.replace(new RegExp('href="'+status.mentions[i].url+'"',"g"),'href="/@'+status.mentions[i].acct+'?mid='+status.mentions[i].id+'" data-mid="'+status.mentions[i].id+'"');
}
if(!status.mentions.find(function(account) {
return account.id == this;
},status.account.id)) {
var writtenby = new Object();
writtenby.id = status.account.id;
writtenby.username = status.account.username;
writtenby.url = status.account.url;
writtenby.acct = status.account.acct;
status.mentions.push(writtenby);
}
if(status.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+status.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -1875,7 +1917,7 @@ ${status.content}
</article>
<footer class="toot_footer"${toot_footer_width}>
<div class="toot_reaction">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}">
<button class="reply_button" tid="${status.id}" mentions='${JSON.stringify(status.mentions)}' display_name="${status.account.display_name}" privacy="${status.visibility}" content_warning="${htmlEscape(status.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>
@ -1929,12 +1971,16 @@ for(var i=0;i<status.reblog.mentions.length;i++) {
if(status.reblog.mentions[i].acct.indexOf("@") == -1) status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'@'+current_instance+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
else status.reblog.content = status.reblog.content.replace(new RegExp('href="'+status.reblog.mentions[i].url+'"',"g"),'href="/@'+status.reblog.mentions[i].acct+'?mid='+status.reblog.mentions[i].id+'" data-mid="'+status.reblog.mentions[i].id+'"');
}
if(!status.reblog.mentions.find(function(account) {
return account.id == this;
},status.reblog.account.id)) {
var writtenby = new Object();
writtenby.id = status.reblog.account.id;
writtenby.username = status.reblog.account.username;
writtenby.url = status.reblog.account.url;
writtenby.acct = status.reblog.account.acct;
status.reblog.mentions.push(writtenby);
}
if(status.reblog.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = "<span>"+status.reblog.spoiler_text+"</span><button class='cw_button'>"+__('SHOW MORE')+"</button>",
article_option = "content_warning";
@ -2031,7 +2077,7 @@ ${status.reblog.content}
</article>
<footer class="toot_footer" style="width:320px">
<div class="toot_reaction">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}">
<button class="reply_button" tid="${status.reblog.id}" mentions='${JSON.stringify(status.reblog.mentions)}' display_name="${status.reblog.account.display_name}" privacy="${status.reblog.visibility}" content_warning="${htmlEscape(status.reblog.spoiler_text)}">
<i class="fa fa-fw fa-reply"></i>
<span class="reaction_count reply_count">${toot_replies_count}</span>
</button>

View File

@ -303,7 +303,6 @@ if(statuses[i].in_reply_to_id && level === "timelines/home" | level === "timelin
if(localStorage.setting_thread_view == "true") {
(function(this_id) {
api.get('statuses/'+statuses[i].id+"/context", function(context) {
console.log(this_id);
for(var b=0;b<context.ancestors.length;b++) {
var filterreplystatus = false;
for(var a=0;a<current_filters.length;a++) {
@ -341,7 +340,8 @@ $(window).scroll(function () {
if ( $(window).scrollTop()+window.innerHeight >= $(document).height()-700 ) {
if (!isSyncing) {
isSyncing = true;
load_options.unshift( {name:"max_id",data:links['next'].match(/max_id=(.+)&?/)[1]} );
if(links && links['next']) {
load_options.unshift({name:"max_id",data:links['next'].match(/max_id=(.+)&?/)[1]});
api.get(level, load_options, function(statuses) {
if (statuses.length) {
for(let i in statuses) {
@ -399,6 +399,12 @@ isSyncing = true;
}
});
load_options.shift();
}
else {
$('.timeline_footer > i').css({"display":"none"});
$('.timeline_footer').append('<img style="width: 30%;opacity: .3;" src="/assets/images/halcyon.png">');
isSyncing = true;
}
};
};
});
@ -1696,6 +1702,10 @@ replyto += "@"+mentions[i].acct+" ";
}
}
$('#reply_status_form textarea').val(replyto);
if($("#reply_status_form .status_spoiler:blank").length == 0) {
$('#reply_status_form .status_spoiler').removeClass('invisible');
$('#reply_status_form .status_textarea').addClass('status_has_cw');
}
delete image_uploads.reply;
image_uploads.reply = new Object();
openStatusEditor("reply");
@ -1748,6 +1758,11 @@ $('#single_reply_status_form .expand_privacy_menu_button > i').attr('class', "fa
$('#single_reply_status_form').attr('tid',sid);
$('.single_reply_status .single_reply_status_header span').addClass("emoji_poss").html(__("Reply to")+" "+display_name);
$('#single_reply_status_form textarea').val(replyto);
$('#single_reply_status_form .status_spoiler').val($(this).attr("content_warning"));
if($(this).attr("content_warning") != "") {
$('#single_reply_status_form .status_spoiler').removeClass('invisible');
$('#single_reply_status_form .status_textarea').addClass('status_has_cw');
}
openStatusEditor("single_reply")
api.get('statuses/'+sid+'/', function(status) {
timeline_template(status).appendTo(".single_reply_status .status_preview");
@ -2029,6 +2044,16 @@ $(".search_form").submit(function(e) {
e.preventDefault();
searchredirect($("#search_form").val());
});
$('.overlay_redirect_invidious_yes').click(function() {
$('.close_button').click();
window.open("https://"+server_setting_invidious+"/watch?v="+$(".overlay_redirect_invidious").data("video"),"_blank");
if($("#redirect_invidious_permanent")[0].checked) localStorage.setting_redirect_invidious = "true";
});
$('.overlay_redirect_invidious_no').click(function() {
$('.close_button').click();
window.open("https://www.youtube.com/watch?v="+$(".overlay_redirect_invidious").data("video"),"_blank");
if($("#redirect_invidious_permanent")[0].checked) localStorage.setting_redirect_invidious = "false";
});
if($("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden");
$("#js-overlay_content_wrap").attrchange(function(attr) {
if(attr == "class" && $("#js-overlay_content_wrap").hasClass("view")) $(document.body).css("overflow-y","hidden");
@ -2072,7 +2097,11 @@ return false;
});
$(document).on('click','.link_preview',function(e) {
e.stopPropagation();
window.open($(this).data("url"),"_blank");
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_-]+)/);
if(ytcom) openVideo(ytcom[2]);
else if(ytbe) openVideo(ytbe[2]);
else window.open($(this).data("url"),"_blank");
});
$(document).on('focus','.status_textarea textarea,.status_top .status_spoiler',function(e) {
global_focus_textfield = $(this).data("random");

View File

@ -13,13 +13,15 @@ getConfig: function(key) {
return config[key];
},
get: function (endpoint) {
var queryData,callback,queryStringAppend = "?";
var queryData,callback,failback,queryStringAppend = "?";
if (typeof arguments[1] === "function") {
queryData = {};
callback = arguments[1];
if(arguments[2]) failback = arguments[2];
} else {
queryData = arguments[1];
callback = arguments[2];
if(arguments[3]) failback = arguments[3];
}
if(typeof queryData == "string") {
queryStringAppend = queryData;
@ -49,6 +51,7 @@ error: function(xhr, textStatus, errorThrown) {
if(xhr.readyState == 0) {
api.get(endpoint,queryStringAppend,callback);
}
else if(typeof failback == "function") failback();
else {
if(xhr.responseText.length > 0) {
putMessage(`[${xhr.status}] ${xhr.responseJSON['error']}`);

View File

@ -1,17 +1,21 @@
; Register App Settings
; The URL Unshortener automatically parses links to URL Shorteners like bit.ly and displays the long version so that the user knows where a link goes
[App]
api_client_name = Your application name
api_client_website = https://example.com/
who_to_follow_provider = https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-osa-api.cgi?{{host}}+{{user}}
default_language = en_US
debug_mode = false
url_unshortener = true
; Media embed settings
; 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
; 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
[Media]
youplay = true
vimeo = true
invidious = invidiou.sh
; 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

View File

@ -28,6 +28,7 @@ View <span></span> new Toots
<aside class="right_column">
<section class="side_widgets_wrap">
<?php include dirname(__FILE__).('/widgets/side_who_to_follow.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_trending.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_firefox_addon.php'); ?>
</section>
<?php include dirname(__FILE__).('/widgets/side_footer.php'); ?>

View File

@ -10,4 +10,5 @@ cs_CZ.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8
nl_NL.UTF-8 UTF-8
ca_ES.UTF-8 UTF-8
ar_DZ.UTF-8 UTF-8
ar_DZ.UTF-8 UTF-8
es_ES.UTF-8 UTF-8

View File

@ -22,6 +22,7 @@
<aside class="right_column">
<section class="side_widgets_wrap">
<?php include dirname(__FILE__).('/widgets/side_who_to_follow.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_trending.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_firefox_addon.php'); ?>
</section>
<?php include dirname(__FILE__).('/widgets/side_footer.php'); ?>

View File

@ -15,6 +15,7 @@ include dirname(__FILE__).('/widgets/overlay_copy_link.php');
include dirname(__FILE__).('/widgets/overlay_confirm.php');
include dirname(__FILE__).('/widgets/overlay_prompt.php');
include dirname(__FILE__).('/widgets/overlay_addlist.php');
include dirname(__FILE__).('/widgets/overlay_redirect_invidious.php');
if($_SERVER["REQUEST_URI"] == "/settings/filters") include dirname(__FILE__).('/widgets/overlay_filter.php');
?>
</div>

View File

@ -73,6 +73,8 @@ resetApp();
}
server_setting_youplay = <?=$config["Media"]["youplay"] ? "true" : "false"?>;
server_setting_vimeo = <?=$config["Media"]["vimeo"] ? "true" : "false"?>;
server_setting_unshorten = <?=$config["App"]["url_unshortener"] ? "true" : "false"?>;
server_setting_invidious = <?=$config["Media"]["invidious"] ? "'".$config["Media"]["invidious"]."'" : "'invidiou.sh'"?>;
</script>
</head>
<body>

View File

@ -22,6 +22,7 @@ View <span></span> new Toots
<aside class="right_column">
<section class="side_widgets_wrap">
<?php include dirname(__FILE__).('/widgets/side_who_to_follow.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_trending.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_firefox_addon.php'); ?>
</section>
<?php include dirname(__FILE__).('/widgets/side_footer.php'); ?>

View File

@ -20,6 +20,7 @@ View <span></span> new Toots
<aside class="right_column">
<section class="side_widgets_wrap">
<?php include dirname(__FILE__).('/widgets/side_who_to_follow.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_trending.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_firefox_addon.php'); ?>
</section>
<?php include dirname(__FILE__).('/widgets/side_footer.php'); ?>

View File

@ -22,6 +22,7 @@
<aside class="right_column">
<section class="side_widgets_wrap">
<?php include dirname(__FILE__).('/widgets/side_who_to_follow.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_trending.php'); ?>
<?php include dirname(__FILE__).('/widgets/side_firefox_addon.php'); ?>
</section>
<?php include dirname(__FILE__).('/widgets/side_footer.php'); ?>

Binary file not shown.

View File

@ -1,14 +1,21 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2019-06-10 14:05+0000\n"
"Last-Translator: ButterflyOfFire <butterflyoffire@protonmail.com>\n"
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-06-21 08:47+0000\n"
"PO-Revision-Date: 2019-08-16 18:57+0000\n"
"Last-Translator: ButterflyOfFire <butterflyoffire+halcyon@protonmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 3.6.1\n"
"X-Generator: Pootle 2.8\n"
"X-Loco-Source-Locale: de_DE\n"
"X-Loco-Parser: loco_parse_po\n"
"X-POOTLE-MTIME: 1565981867.626590\n"
msgid "Language"
msgstr "اللغة"
@ -16,15 +23,9 @@ msgstr "اللغة"
msgid "Language_en_US"
msgstr "الإنجليزية (أمريكا)"
msgid "Language_cs_CZ"
msgstr "التشيكية"
msgid "Language_de_DE"
msgstr "الألمانية"
msgid "Language_fr_FR"
msgstr "الفرنسية"
msgid "Language_ja_JP"
msgstr "اليابانية"
@ -43,6 +44,21 @@ msgstr "البرتغالية (البرازيل)"
msgid "Language_it_IT"
msgstr "الإيطالية"
msgid "Language_cs_CZ"
msgstr "التشيكية"
msgid "Language_fr_FR"
msgstr "الفرنسية"
msgid "Language_nl_NL"
msgstr "الهولندية"
msgid "Language_ca_ES"
msgstr "الكتالانية"
msgid "Language_ar_DZ"
msgstr "العربية"
msgid "Sensitive content"
msgstr "محتوى حساس"
@ -94,9 +110,24 @@ msgstr "عر الأصلي"
msgid "Boosted"
msgstr "تمت ترقيته"
msgid "Pinned Toot"
msgstr "تبويق مدبس"
msgid "favourited Your Toot"
msgstr "أعجب بتبويقك"
msgid "boosted Your Toot"
msgstr "قام بترقية تبويقك"
msgid "followed you"
msgstr "يتابِعك"
msgid "Follow"
msgstr "تابع"
msgid "Toot your reply"
msgstr ""
msgid "Reply"
msgstr "رد"
@ -139,18 +170,93 @@ msgstr "نوف"
msgid "Dec"
msgstr "ديس"
msgid "Changed setting to"
msgstr ""
msgid "Mark as NSFW by default enabled"
msgstr ""
msgid "Mark as NSFW by default disabled"
msgstr ""
msgid "Who to follow enabled"
msgstr ""
msgid "Who to follow disabled"
msgstr ""
msgid "Changed about me setting"
msgstr ""
msgid "Uploaded new avatar"
msgstr ""
msgid "Uploaded new header"
msgstr ""
msgid "Account locked"
msgstr "الحساب مؤمّن"
#, fuzzy
msgid "Account unlocked"
msgstr "الحساب مؤمّن"
msgid "Link previews enabled"
msgstr "معاينة الروابط مفعّلة"
#, fuzzy
msgid "Link previews disabled"
msgstr "معاينة الروابط مفعّلة"
msgid "You didn't allow notifications"
msgstr ""
msgid "Desktop notifications enabled"
msgstr "إشعارات سطح المكتب مفعّلة"
#, fuzzy
msgid "Desktop notifications disabled"
msgstr "إشعارات سطح المكتب مفعّلة"
msgid "Replies shown"
msgstr ""
msgid "Replies hidden"
msgstr ""
msgid "CW content shown"
msgstr ""
msgid "CW content hidden"
msgstr ""
msgid "NSFW content shown"
msgstr ""
msgid "NSFW content hidden"
msgstr ""
msgid "Reply to"
msgstr "ردا على"
msgid "Report"
msgstr "الإبلاغ"
msgid "Report a Toot of"
msgstr ""
msgid "What's happening?"
msgstr "ما الحدث؟"
msgid "Toot"
msgstr "بوّق"
msgid "Compose new Toot"
msgstr "تحرير تبويق جديد"
msgid "Please describe what the problem with the Toot is."
msgstr ""
msgid "TOOTS"
msgstr "تبويقات"
@ -160,9 +266,30 @@ msgstr "الأشخاص"
msgid "Settings"
msgstr "الإعدادات"
msgid "GENERAL"
msgstr "عام"
msgid "PROFILE"
msgstr "الملف الشخصي"
msgid "APPEARANCE"
msgstr "المظهر"
msgid "Change instance"
msgstr "تغيير مثيل الخادم"
msgid "Blank for default"
msgstr "فارغ للافتراضي"
msgid "FOLLOWING"
msgstr "المتابَعون"
msgid "Interesting accounts of devs"
msgstr ""
msgid "Halcyon for"
msgstr "هالسيون Halcyon لـ"
msgid "About"
msgstr "عن"
@ -187,6 +314,15 @@ msgstr "الإصدار"
msgid "Who to follow"
msgstr "مَن عليك متابَعته"
msgid "Enable who to follow"
msgstr "تفعيل مَن عليك متابَعته"
msgid ""
"Halcyon needs to connect to an external server to get a list of users which "
"have similar interests as you. If you want to use this feature, please opt-"
"in."
msgstr ""
msgid "MORE"
msgstr "المزيد"
@ -196,6 +332,27 @@ msgstr "المتابِعون"
msgid "Following"
msgstr "المتابَعون"
msgid "You'll no longer receive notifications from this user"
msgstr ""
msgid "Unmuted this user"
msgstr ""
msgid "This user has been blocked"
msgstr ""
msgid "Unblocked this user"
msgstr ""
msgid "Your Toot has been deleted"
msgstr "لقد تم حذف تبويقك"
msgid "Your Toot has been pinned"
msgstr "تم تدبيس تبويقك"
msgid "Your Toot has been unpinned"
msgstr "تم فك تدبيس تبويقك"
msgid "Edit profile"
msgstr "تعديل الملف الشخصي"
@ -205,15 +362,30 @@ msgstr "المفضلة"
msgid "Show"
msgstr "عرض"
msgid "Blocking"
msgstr ""
msgid "Muting"
msgstr ""
msgid "Requested"
msgstr ""
msgid "Photos and toots"
msgstr "الصور والتبويقات"
msgid "favourited your toot"
msgstr "أعجِب بتبويقك"
msgid "boosted your toot"
msgstr "قام بترقية تبويقك"
msgid "mentioned you"
msgstr "أشار إليك"
msgid "Your Toot was posted!"
msgstr "تم نشر تبويقك!"
msgid "News"
msgstr "المستجدات"
@ -223,6 +395,9 @@ msgstr "المصدر"
msgid "Privacy"
msgstr "الخصوصية"
msgid "Imprint"
msgstr ""
msgid "Contact"
msgstr "للاتصال"
@ -238,15 +413,43 @@ msgstr "إنشاء حساب"
msgid "or"
msgstr "أو"
msgid "I agree with the"
msgstr "أوافق على"
msgid "What is Halcyon"
msgstr "ما هو هالسيون Halcyon"
msgid ""
"which aims to recreate the simple and beautiful user interface of Twitter "
"while keeping all advantages of decentral networks in focus."
msgstr ""
msgid "Halcyon is a webclient for"
msgstr "هالسيون Halcyon تطبيق ويب لـ"
msgid "Contact / Feedback"
msgstr ""
msgid "Use my contact form"
msgstr ""
msgid "Help us"
msgstr "ساعدنا"
msgid "Halcyon Terms of Use"
msgstr "شروط خدمة هالسيُون"
msgid ""
"This terms of use agreement is for the users of web service Halcyon for "
"Mastodon and Pleroma (Halcyon for short) hosted at"
msgstr ""
msgid "Your Reply was posted!"
msgstr "تم نشر جوابك!"
msgid "Toot reported successfully!"
msgstr "تم الإبلاغ عن التبويق بنجاح!"
msgid "Link successfully copied!"
msgstr "تم نسخ الرابط بنجاح!"
@ -277,6 +480,12 @@ msgstr "الكل"
msgid "new notitification"
msgstr "إشعار جديد"
msgid "Show all NSFW content"
msgstr "أظهر كافة المحتويات الحساسة"
msgid "Show all CW content"
msgstr ""
msgid "Show replies"
msgstr "عرض الردود"
@ -295,6 +504,9 @@ msgstr "تحديث يدوي"
msgid "Appearance settings"
msgstr "إعدادات المظهر"