diff --git a/README.md b/README.md
index 206646c..95f018d 100644
--- a/README.md
+++ b/README.md
@@ -20,12 +20,14 @@ We moved our instances list to our webpage: https://www.halcyon.social/instances
- No tracking, No ads.
- Supports multiple languages.
- Privacy-friendly video embeds.
+- Full support for Mastodon polls.
## Install
[![Install Halcyon with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=halcyon)
or read our new documentation pages to install it manually: https://www.halcyon.social/documentation.php?page=install
## Blog
+- Release of Version 2.3.0 - Blog article will be published soon
- Release of Version 2.2.5 - Add French translation,improve German translation,add support for video captions,add support for video thumbnails
- Release of Version 2.2.4 - Easily switch between pictures in overlay,show pictures in full height in timeline,duplicated threads removed,many smaller bugfixes
- Release of Version 2.2.3 - Fixed login with Pleroma,fixed compatibility with Pawoo (older Mastodon),added support for prefers-color-scheme,some more fixes
diff --git a/assets/css/dark.css b/assets/css/dark.css
index d1e18bd..80a3fda 100644
--- a/assets/css/dark.css
+++ b/assets/css/dark.css
@@ -21,6 +21,10 @@ background-color:#243447!important;
background-color:#189EFC !important;
opacity:0.5;
}
+.status_form .status_bottom .disabled {
+color:#189EFC !important;
+opacity:0.5;
+}
.status_form .status_top .status_spoiler {
color:#fff;
border:1px solid #000;
@@ -34,7 +38,8 @@ background-color:#132030;
background-color: #132030;
color:#fff;
}
-.status_form .status_textarea .media_attachments_preview_area {
+.status_form .status_textarea .media_attachments_preview_area,
+.status_form .status_textarea .status_poll_editor {
background-color:#1B2836;
border-top:1px solid #000;
}
@@ -52,6 +57,22 @@ background-color:rgba(0,0,0,0);
color:#fff;
background-color:rgba(0,0,0,.8);
}
+.poll_time {
+color: #FFFFFF;
+border:1px solid #AAB8C2;
+background-color:#1B2836;
+}
+.poll_time:focus-within {
+border:1px solid #189EFC;
+background-color:#1B2836;
+}
+.poll_time.redborder {
+border:1px solid #FF0000;
+}
+.poll_time input {
+color:#FFFFFF;
+background-color:#1B2836;
+}
.status_form .status_bottom .status_option_button {
color:#189EFC;
}
@@ -459,7 +480,7 @@ color:#999;
.toot_detail {
background-color:#1B2836;
}
-.toot_entry.ancestors_status .toot_entry_body::after,.toot_entry.descendants_status .toot_entry_body::after {
+.toot_entry.ancestors_status .toot_entry_body::after,.toot_entry.descendants_status.direct_answer .toot_entry_body::after {
border:2px solid #76BFEC;
}
.toot_entry.descendants_status:last-child .toot_entry_body::after {
@@ -495,12 +516,11 @@ background:#243447;
background:#189EFC;
}
.radiobox input[type="radio"] + .radiotext:before {
-background:#243447;
border:1px solid #AAB8C2;
}
.radiobox input[type="radio"]:checked + .radiotext:before {
background-color:#189EFC;
-box-shadow:inset 0 0 0 4px #fff;
+box-shadow: inset 0 0 0 4px #243447;
border-color:#189EFC;
}
.options {
@@ -631,3 +651,12 @@ background: rgb(101, 119, 134);
.player .volume .pointer {
background: #189EFC;
}
+.poll_bar {
+background-color:rgb(101, 119, 134);
+}
+.poll_winner {
+background-color:#189EFC;
+}
+.poll_footer {
+color:#66757f;
+}
diff --git a/assets/css/style.css b/assets/css/style.css
index ad401b0..9712557 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -131,6 +131,11 @@ background-color: #A3D8FF!important;
pointer-events: none;
cursor: default;
}
+.status_form .status_bottom .disabled {
+color: #A3D8FF!important;
+pointer-events: none;
+cursor: default;
+}
.status_form .status_top {
display: flex;
align-items: center;
@@ -185,14 +190,21 @@ overflow: hidden;
.status_form .status_textarea textarea.focus {
height: 68px;
}
-.status_form .status_textarea .media_attachments_preview_area {
-display: flex;
-flex-wrap: nowrap;
+.status_form .status_textarea .media_attachments_preview_area,
+.status_form .status_textarea .status_poll_editor {
margin: 8px -8px -8px -8px;
padding: 8px 12px;
background-color: #F1F1F1;
border-top: 1px solid #C7E7FB;
}
+.status_form .status_textarea.closed .media_attachments_preview_area,
+.status_form .status_textarea.closed .status_poll_editor {
+display:none;
+}
+.status_form .status_textarea .media_attachments_preview_area {
+display: flex;
+flex-wrap: nowrap;
+}
.status_form .status_textarea .media_attachments_preview {
position: relative;
flex-shrink: 0;
@@ -245,6 +257,57 @@ justify-content: center;
font-size: 14px;
margin: 4px 4px 0 0;
}
+.status_form .status_textarea .status_poll_editor .poll_field {
+margin:5px;
+width:calc(100% - 29px);
+}
+input[type='number'] {
+-moz-appearance:textfield;
+}
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+-webkit-appearance:none;
+}
+.poll_time {
+margin-top:5px;
+padding-right:10px;
+font-size: 14px;
+color: #66757F;
+box-sizing: border-box;
+height:30px;
+border:1px solid #AAB8C2;
+border-radius:2px;
+background-color:#FFFFFF;
+display:inline-block;
+}
+.poll_time:focus-within {
+border:1px solid #189EFC;
+background-color:#FFFFFF;
+}
+.poll_time.redborder {
+border:1px solid #FF0000;
+}
+.poll_time input {
+outline:0;
+border:0;
+height:28px;
+max-width:60px;
+border-radius:2px;
+padding-left:5px;
+text-align:center;
+color: #66757F;
+}
+.poll_time input:focus {
+outline:0;
+}
+.poll_time input:invalid {
+box-shadow:none;
+}
+.poll_mc_switch {
+margin:0 !important;
+display:inline-block;
+vertical-align:middle;
+}
.status_form .status_bottom {
display: flex;
align-items: center;
@@ -874,7 +937,6 @@ border: 1px solid #DCDFE1;
}
.media_views.media_full_height {
height:auto;
-min-height:336px;
}
.media_views .media_attachment {
overflow: hidden;
@@ -980,6 +1042,11 @@ font-size: 14px;
line-height: 18px;
border-bottom: 1px solid #E6ECF0;
}
+.timeline .poll_notify_header {
+padding: 10px 0 0 70px !important;
+font-size: 14px;
+line-height: 18px;
+}
.timeline .notice_entry .notice_entry_body {
width: 480px;
border: 1px solid #E6ECF0;
@@ -1003,7 +1070,7 @@ overflow: hidden;
.timeline .notice_entry .icon_box img {
width: 24px;
}
-.timeline .notice_entry .font-icon {
+.timeline .toot_entry .font-icon {
position: relative;
padding: 3px;
left: -23px;
@@ -1013,28 +1080,32 @@ font-size: 10px;
border-radius: 3px;
color: #fff;
}
-.timeline .notice_entry .font-icon.follow {
+.timeline .toot_entry .font-icon.follow {
background: #1DA1F2;;
}
-.timeline .notice_entry .font-icon.boost {
+.timeline .toot_entry .font-icon.boost {
background: #17BF63;
}
-.timeline .notice_entry .font-icon.favourite {
+.timeline .toot_entry .font-icon.favourite {
background: #FFAD1A;
}
-.timeline .notice_entry .notice_author_box {
+.timeline .toot_entry .font-icon.poll {
+background: #FF4040;
+top:0;
+}
+.timeline .toot_entry .notice_author_box {
padding: 3px 0;
}
-.timeline .notice_entry .notice_author_box > a.notice_author {
+.timeline .toot_entry .notice_author_box > a.notice_author {
margin-left: -18px;
}
-.timeline .notice_entry .notice_author_box > a.notice_author span {
+.timeline .toot_entry .notice_author_box > a.notice_author span {
font-weight: 600;
}
-.timeline .notice_entry .toot_content .toot_header a .displayname {
+.timeline .toot_entry .toot_content .toot_header a .displayname {
font-weight: 600;
}
-.timeline .notice_entry .toot_content .toot_header a .username {
+.timeline .toot_entry .toot_content .toot_header a .username {
color: #66757F;
}
.timeline .toot_entry .toot_content .toot_article .status_content p:not(:last-child) {
@@ -1355,13 +1426,13 @@ box-sizing: border-box;
height:30px;
border:1px solid #AAB8C2;
border-radius:2px;
-background-color:transparent;
+background-color:#FFFFFF;
outline:0;
}
.textfield:focus {
outline:0;
border:1px solid #189EFC;
-background-color:transparent;
+background-color:#FFFFFF;
}
.account_box {
display: flex;
@@ -2557,7 +2628,7 @@ opacity: 0;
}
.radiobox input[type="radio"] + .radiotext:before {
content: '';
-background: #ffffff;
+background: transparent;
border-radius: 100%;
border: 1px solid #AAB8C2;
display: inline-block;
@@ -2573,7 +2644,7 @@ top: -8px;
}
.radiobox input[type="radio"]:checked + .radiotext:before {
background-color: #189EFC;
-box-shadow: inset 0 0 0 4px #ffffff;
+box-shadow: inset 0 0 0 4px #FFF;
outline: none;
border-color: #189EFC;
}
@@ -2801,3 +2872,48 @@ background: #189EFC;
-moz-border-radius: 50%;
border-radius: 50%;
}
+.poll_box {
+position:relative;
+}
+.poll_box_form {
+line-height:20px;
+}
+.poll_box .radiobox {
+margin:0;
+margin-top:10px;
+}
+.poll_checkbox_label {
+line-height:30px;
+}
+.poll_checkbox_label:before {
+vertical-align:top !important;
+}
+.toot_detail.main_status .poll_checkbox_label:before {
+vertical-align:middle !important;
+}
+.poll_vote {
+display:inline;
+}
+.toot_detail.main_status .poll_vote {
+vertical-align:text-bottom;
+}
+.poll_bar {
+position:absolute;
+background-color:#CCCCCC;
+border-radius:4px;
+height:25px;
+}
+.poll_winner {
+background-color:#189EFC;
+}
+.toot_detail.main_status .poll_bar {
+height:35px;
+}
+.poll_result_label {
+position:relative;
+display:inline-block;
+padding:5px;
+}
+.poll_footer {
+color:#66757F;
+}
diff --git a/assets/js/halcyon/halcyonTemplates.js b/assets/js/halcyon/halcyonTemplates.js
index d04eac6..eb90602 100644
--- a/assets/js/halcyon/halcyonTemplates.js
+++ b/assets/js/halcyon/halcyonTemplates.js
@@ -7,7 +7,7 @@ if(status.media_attachments[0].remote_url != null) {
status.media_attachments[0].url = status.media_attachments[0].remote_url;
}
if(status.media_attachments[0].type === "video" && localStorage.setting_play_video != "false") border = ' style="border:0;border-radius:0"';
-if(localStorage.setting_full_height == "true") {
+if(localStorage.setting_full_height == "true" && status.media_attachments.length == 1 && (status.media_attachments[0].type == "image" || (status.media_attachments[0].type === "video" && localStorage.setting_play_video == "false") || (status.media_attachments[0].type === "gifv" && localStorage.setting_play_gif == "false"))) {
mvfullheight = " media_full_height";
dsplength = "1";
}
@@ -82,6 +82,52 @@ media_views += "";
}
return media_views;
}
+function poll_template(poll) {
+let poll_html = "";
+var expires_at = new Date(new Date(poll.expires_at).getTime()-Date.now());
+var expires_string;
+if(expires_at.getUTCDate() == 2) expires_string = "1 "+__("day");
+else if(expires_at.getUTCDate() > 2) expires_string = (expires_at.getUTCDate()-1)+" "+__("days");
+else if(expires_at.getUTCHours() == 1) expires_string = "1 "+__("hour");
+else if(expires_at.getUTCHours() > 1) expires_string = expires_at.getUTCHours()+" "+__("hours");
+else if(expires_at.getUTCMinutes() == 1) expires_string = "1 "+__("minute");
+else if(expires_at.getUTCMinutes() > 1) expires_string = expires_at.getUTCMinutes()+" "+__("minutes");
+else if(expires_at.getUTCSeconds() == 1) expires_string = "1 "+__("second");
+else expires_string = expires_at.getUTCSeconds()+" "+__("seconds");
+if(poll.voted || poll.expired) {
+poll_html = (`
`);
+optionsort = [...poll.options];
+optionsort.sort(function(a,b) {return a.votes_count - b.votes_count});
+optionsort.reverse();
+if(optionsort[0].votes_count != optionsort[1].votes_count) poll.options[poll.options.indexOf(optionsort[0])].winner = true;
+for(var i=0;i
+`);
+}
+if(poll.expired) poll_html += (`
`);
+else poll_html += (`
`);
+}
+else {
+const poll_random = Math.round(Math.random()*1000);
+poll_html = (``);
+return poll_html;
+}
function timeline_template(status) {
if (status.reblog === null) {
for(i=0;i",
article_option = "content_warning";
@@ -128,9 +175,12 @@ toot_reblogs_count = status.reblogs_count;
if (status.favourites_count) {
toot_favourites_count = status.favourites_count;
}
-if ( status.media_attachments.length ) {
+if(status.media_attachments.length) {
media_views = mediaattachments_template(status);
}
+if(status.poll) {
+poll_object = poll_template(status.poll);
+}
if(status.account.display_name.length == 0) {
status.account.display_name = status.account.username;
}
@@ -238,6 +288,7 @@ ${toot_reblog_button}
`);
html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
return html
} else {
for(i=0;i",
article_option = "content_warning";
@@ -293,6 +345,9 @@ toot_favourites_count = status.reblog.favourites_count;
if ( status.reblog.media_attachments.length ) {
media_views = mediaattachments_template(status.reblog);
}
+if(status.reblog.poll) {
+poll_object = poll_template(status.reblog.poll);
+}
if(status.account.display_name.length == 0) {
status.account.display_name = status.account.username;
}
@@ -398,6 +453,7 @@ ${status.reblog.content}
`);
html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
return html
}
}
@@ -429,7 +485,8 @@ article_option= "",
toot_replies_count = "",
toot_reblogs_count= "",
toot_favourites_count = "",
-media_views = "";
+media_views = "",
+poll_object = "";
if(status.spoiler_text && localStorage.setting_show_content_warning == "false") {
alart_text = ""+status.spoiler_text+"",
article_option = "content_warning";
@@ -449,6 +506,9 @@ toot_favourites_count = status.favourites_count;
if ( status.media_attachments.length ) {
media_views = mediaattachments_template(status);
}
+if(status.poll) {
+poll_object = poll_template(status.poll);
+}
if(status.account.display_name.length == 0) {
status.account.display_name = status.account.username;
}
@@ -544,6 +604,7 @@ ${status.content}
`);
html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
return html
}
function notifications_template(NotificationObj) {
@@ -557,7 +618,7 @@ NotificationObj.account.display_name = htmlEscape(NotificationObj.account.displa
for(i=0;i");
}
-if ( NotificationObj.type === 'favourite' | NotificationObj.type === 'reblog' ) {
+if (NotificationObj.type === 'favourite' | NotificationObj.type === 'reblog' ) {
var toot_author_link;
if(NotificationObj.status.account.acct.indexOf("@") == -1) toot_author_link = "/@"+NotificationObj.status.account.acct+"@"+current_instance+"?mid="+NotificationObj.status.account.id;
else toot_author_link = "/@"+NotificationObj.status.account.acct+"?mid="+NotificationObj.status.account.id;
@@ -676,7 +737,8 @@ article_option= "",
toot_replies_count = "",
toot_reblogs_count= "",
toot_favourites_count = "",
-media_views = "";
+media_views = "",
+poll_object = "";
for(i=0;i");
}
@@ -713,6 +775,9 @@ toot_favourites_count = NotificationObj.status.favourites_count;
if (NotificationObj.status.media_attachments.length) {
media_views = mediaattachments_template(NotificationObj.status);
}
+if(NotificationObj.status.poll) {
+poll_object = poll_template(NotificationObj.status.poll);
+}
if(NotificationObj.status.account.display_name.length == 0) {
NotificationObj.status.account.display_name = NotificationObj.status.account.username;
}
@@ -820,8 +885,176 @@ ${toot_reblog_button}
`);
html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
return html
-} else {
+} else if ( NotificationObj.type === 'poll' ) {
+var toot_author_link;
+if(NotificationObj.status.account.acct.indexOf("@") == -1) toot_author_link = "/@"+NotificationObj.status.account.acct+"@"+current_instance+"?mid="+NotificationObj.status.account.id;
+else toot_author_link = "/@"+NotificationObj.status.account.acct+"?mid="+NotificationObj.status.account.id;
+const toot_datetime= getRelativeDatetime(Date.now(), getConversionedDate(null, NotificationObj.status.created_at)),
+toot_attr_datetime = getConversionedDate(null, NotificationObj.status.created_at);
+let alart_text= "",
+article_option= "",
+toot_replies_count = "",
+toot_reblogs_count= "",
+toot_favourites_count = "",
+media_views = "",
+poll_object = "";
+for(i=0;i");
+}
+NotificationObj.status.account.display_name = htmlEscape(NotificationObj.status.account.display_name);
+for(i=0;i");
+}
+for(var i=0;i"+NotificationObj.status.spoiler_text+"",
+article_option = "content_warning";
+}
+else if(NotificationObj.status.spoiler_text && localStorage.setting_show_content_warning == "true") {
+alart_text = ""+NotificationObj.status.spoiler_text+"";
+}
+if(NotificationObj.status.replies_count) {
+toot_replies_count = NotificationObj.status.replies_count;
+}
+if (NotificationObj.status.reblogs_count) {
+toot_reblogs_count = NotificationObj.status.reblogs_count;
+}
+if (NotificationObj.status.favourites_count) {
+toot_favourites_count = NotificationObj.status.favourites_count;
+}
+if (NotificationObj.status.media_attachments.length) {
+media_views = mediaattachments_template(NotificationObj.status);
+}
+if(NotificationObj.status.poll) {
+poll_object = poll_template(NotificationObj.status.poll);
+}
+if(NotificationObj.status.account.display_name.length == 0) {
+NotificationObj.status.account.display_name = NotificationObj.status.account.username;
+}
+switch(NotificationObj.status.visibility) {
+case "public":toot_privacy_mode=__("Public");toot_privacy_icon="globe";break;
+case "unlisted":toot_privacy_mode=__("Unlisted");toot_privacy_icon="unlock-alt";break;
+case "private":toot_privacy_mode=__("Followers-only");toot_privacy_icon="lock";break;
+case "direct":toot_privacy_mode=__("Direct");toot_privacy_icon="envelope";break;
+}
+if(toot_privacy_icon == "globe" || toot_privacy_icon == "unlock-alt") {
+toot_footer_width = " style='width:320px'";
+toot_reblog_button = (`
+
+
`);
+}
+else {
+toot_footer_width = "";
+toot_reblog_button = "";
+}
+var own_toot_buttons = "";
+if(NotificationObj.status.account.acct == current_acct) {
+var own_toot_buttons = (`${__('Delete Toot')}`);
+if(NotificationObj.status.pinned == true) {
+own_toot_buttons += (`${__('Unpin Toot')}`);
+}
+else {
+own_toot_buttons += (`${__('Pin Toot')}`);
+}
+}
+else {
+var own_toot_buttons = (`${__('Mute')} @${NotificationObj.status.account.username}
+${__('Block')} @${NotificationObj.status.account.username}
+${__('Add to list')} @${NotificationObj.status.account.username}
+${__('Report this Toot')}`);
+}
+var account_state_icons = "";
+if(NotificationObj.status.account.locked == true) account_state_icons += " ";
+if(NotificationObj.status.account.bot == true) account_state_icons += " ";
+const html=$(`
+
+
+
+
+
+
+
+
+
+
+
+${alart_text}
+
+${NotificationObj.status.content}
+
+
+
+
+
+`);
+html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
+return html
+} else if(NotificationObj.type === 'follow') {
const html=(`
@@ -896,7 +1129,8 @@ article_option= "",
toot_replies_count = "",
toot_reblogs_count= "",
toot_favourites_count = "",
-media_views = "";
+media_views = "",
+poll_object = "";
for(i=0;i
");
}
@@ -933,6 +1167,9 @@ toot_favourites_count = status.favourites_count;
if (status.media_attachments.length) {
media_views = mediaattachments_template(status);
}
+if(status.poll) {
+poll_object = poll_template(status.poll);
+}
if(status.account.display_name.length == 0) {
status.account.display_name = status.account.username;
}
@@ -1052,6 +1289,23 @@ ${toot_reblog_button}
@@ -1087,6 +1341,9 @@ ${toot_reblog_button}
+
@@ -1115,6 +1372,7 @@ ${current_instance_charlimit}
`);
history.pushState(null, null, status_account_link.replace("?mid=",'/status/'+status.id+"?mid="));
html.find(".toot_article").append(media_views);
+html.find(".toot_article").append(poll_object);
return html
} else {
const status_datetime= getConversionedDate(null, status.reblog.created_at),
@@ -1129,7 +1387,8 @@ article_option= "",
toot_replies_count = "",
toot_reblogs_count= "",
toot_favourites_count = "",
-media_views = "";
+media_views = "",
+poll_object = "";
for(i=0;i");
}
@@ -1170,6 +1429,9 @@ toot_favourites_count = status.reblog.favourites_count;
if(status.reblog.media_attachments.length){
media_views = mediaattachments_template(status.reblog);
}
+if(status.reblog.poll) {
+poll_object = poll_template(status.reblog.poll);
+}
if(status.account.display_name.length == 0) {
status.account.display_name = status.account.username;
}
@@ -1280,6 +1542,23 @@ ${status.reblog.content}
@@ -1315,7 +1594,10 @@ ${status.reblog.content}
-