From 523c1fab2f5caf782519c6880298265291908b58 Mon Sep 17 00:00:00 2001 From: nipos <ni.pos@yandex.com> Date: Sat, 19 May 2018 19:52:19 +0200 Subject: [PATCH] Complete rewrite of the who to follow function --- README.md | 8 ++- assets/css/style.css | 28 ++++++-- assets/js/halcyon/halcyonFunctions.js | 96 ++++++++++++++++++++++----- assets/js/halcyon/halcyonUI.js | 24 ++----- config.ini.sample | 2 +- footer.php | 33 --------- login/auth.php | 4 +- version.txt | 2 +- widgets/side_who_to_follow.php | 27 +++++++- 9 files changed, 143 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index a13be42..e278821 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,17 @@ Follow or Mastodon account and never miss an important update: [@halcyon@social. ## Instances These instances are publicly accessible and usable by everyone, no matter which Mastodon instance you use. -- https://halcyon.toromino.de - 1.1.5 -- https://social.dev-wiki.de - 1.1.5 +- https://halcyon.toromino.de - 1.1.6 +- https://social.dev-wiki.de - 1.1.6 - https://halcyon.bka.li - 1.1.5 -- https://itter.photog.social - 1.1.4 +- https://itter.photog.social - 1.1.5 - https://halcyon.tilde.team - 1.1.3 - https://halcyon.cybre.space - Outdated You have your own Halcyon instance and want it to be listed here? Create an issue with the link and we will add it to the list. ## Blog +- Release of Version 1.1.6 - Complete rewrite of the "who to follow" function using an API - Change of config.ini needed! - Release of Version 1.1.5 - Introduced the new Idempotency-Key Header and fixed an bug allowing XSS with the display name - Release of Version 1.1.4 - Automatically reconnect on bad connection,now supports desktop notifications,added ... at the end of shortened links - Release of Version 1.1.3 - New function link previews introduced and bug when replying an toot which already has replies below it fixed (reply to undefined) @@ -47,3 +48,4 @@ Upload it, edit config.ini and have fun! ## Credits - [Kirschn/mastodon.js](https://github.com/Kirschn/mastodon.js) - [yks118/Mastodon-api-php](https://github.com/yks118/Mastodon-api-php) +- [distsn/vinayaka](https://github.com/distsn/vinayaka) diff --git a/assets/css/style.css b/assets/css/style.css index 43e26de..13bd023 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -571,10 +571,9 @@ margin-right: 4px; .relationship_button span { font-weight: 600; } -.follow_button {border: 1px solid #189EFC; color: #189EFC;} -.follow_button i {color: #189EFC} -.follow_button:hover, -.follow_button:hover i {background-color: #189EFC;color: #fff;} +.follow_button,.halcyon_button {border: 1px solid #189EFC; color: #189EFC;} +.follow_button i,.halcyon_button i {color: #189EFC} +.follow_button:hover,.follow_button:hover i,.halcyon_button:hover,.halcyon_button:hover i {background-color: #189EFC;color: #fff;} .following_button, .following_button i {background-color: #189EFC;color: #fff;} .following_button:hover, @@ -1377,6 +1376,27 @@ font-weight: 600; background-color: #189EFC; color: #fff!important; } +.halcyon_button { +display: flex; +flex-wrap: nowrap; +align-items: center; +font-size: 12px; +padding: 5px 16px; +margin-top: 4px; +border-radius: 4px; +} +.halcyon_button i { +color: #189EFC; +margin-right: 4px; +} +.halcyon_button span { +font-weight: 600; +} +.halcyon_button:hover, +.halcyon_button:hover i { +background-color: #189EFC; +color: #fff!important; +} .side_widget .account_box .label_box .following_button { display: flex; color: #fff; diff --git a/assets/js/halcyon/halcyonFunctions.js b/assets/js/halcyon/halcyonFunctions.js index 2fc050b..e56b2be 100644 --- a/assets/js/halcyon/halcyonFunctions.js +++ b/assets/js/halcyon/halcyonFunctions.js @@ -186,6 +186,7 @@ localStorage.setItem("current_statuses_count_link", getRelativeURL(AccountObj["u localStorage.setItem("current_following_count_link", getRelativeURL(AccountObj["url"],AccountObj["id"],'/following')); localStorage.setItem("current_followers_count_link", getRelativeURL(AccountObj["url"],AccountObj["id"],'/followers')); localStorage.setItem("current_favourites_link", getRelativeURL(AccountObj["url"],AccountObj["id"],'/favourites')); +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"); @@ -198,26 +199,18 @@ current_statuses_count_link = localStorage.getItem("current_statuses_count_link" current_following_count_link = localStorage.getItem("current_following_count_link"); current_followers_count_link = localStorage.getItem("current_followers_count_link"); current_favourites_link = localStorage.getItem("current_favourites_link"); -$(".js_current_profile_displayname").text(current_display_name); -$(".js_current_profile_username").text(current_acct); -$(".js_current_profile_link").attr('href', current_url); -$(".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_statuses_count_link); -$(".current_following_count_link").attr('href', current_following_count_link); -$(".current_followers_count_link").attr('href', current_followers_count_link); -replace_emoji(); +setCurrentProfile(); }); api.get("accounts/"+current_id+"/following",function(data) { followings = new Array(); for(i=0;i<data.length;i++) { -followings.push(data[i].id); +if(data[i].acct.indexOf("@") == -1) { +data[i].acct = data[i].acct+"@"+current_instance; } -localStorage.setItem("current_following_ids",JSON.stringify(followings)); -current_following_ids = followings; +followings.push(data[i].acct); +} +localStorage.setItem("current_following_accts",JSON.stringify(followings)); +current_following_accts = followings; }); api.get("instance",function(data) { if(data.max_toot_chars) { @@ -251,8 +244,9 @@ current_statuses_count_link = localStorage.getItem("current_statuses_count_link" current_following_count_link = localStorage.getItem("current_following_count_link"); current_followers_count_link = localStorage.getItem("current_followers_count_link"); current_favourites_link = localStorage.getItem("current_favourites_link"); -current_following_ids = localStorage.getItem("current_following_ids"); +current_following_accts = localStorage.getItem("current_following_accts"); current_instance_charlimit = localStorage.getItem("current_instance_charlimit"); +$(function() {setCurrentProfile()}); } function setCurrentProfile() { $(".js_current_profile_displayname").text(current_display_name); @@ -284,6 +278,9 @@ localStorage.setItem("setting_desktop_notifications","false"); $("#setting_desktop_notifications")[0].checked = false; } } +if(localStorage.setting_who_to_follow == "true") { +setWhoToFollow(); +} replace_emoji(); } function putMessage(Message) { @@ -309,3 +306,70 @@ return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } +function randomNumber(min,max) { +return Math.floor(Math.random() * (max - min)) + min; +} +function setWhoToFollow(sanimate) { +if(sanimate == true) { +$(".follow_opt_in").slideUp(function() {$(".follow_loading").slideDown()}); +} +else { +$(".follow_opt_in").hide(); +$(".follow_loading").show(); +} +if(localStorage.current_follow_loaded == "true") { +if(localStorage.who_to_follow) { +follow_loaded = 0; +var wtflist = JSON.parse(localStorage.who_to_follow); +addFollowProfile(0,wtflist[randomNumber(0,wtflist.length)]); +addFollowProfile(1,wtflist[randomNumber(0,wtflist.length)]); +addFollowProfile(2,wtflist[randomNumber(0,wtflist.length)]); +var checkload = setInterval(function() { +if(follow_loaded == 3) { +clearInterval(checkload); +$(".follow_loading").hide(); +$(".what_to_follow").show(); +} +},100); +} +else { +$("#follow_icon").removeClass("fa-circle-o-notch").removeClass("fa-spin").addClass("fa-id-card-o").addClass("fa-stack-1x").after($("<i>").addClass("fa").addClass("fa-ban").addClass("fa-stack-2x")); +} +} +else { +var url = $("#who-to-follow-provider").html(); +url = url.replace(/{{host}}/g, encodeURIComponent(current_instance)); +url = url.replace(/{{user}}/g, encodeURIComponent(current_acct)); +$.ajax(url).done(function(data) { +localStorage.current_follow_loaded = true; +if(data.status == 200) { +var wtflist = new Array(); +for(i=0;i<data.ids.length;i++) { +if(current_following_accts.indexOf(data.ids[i].to_id) == -1) { +wtflist.push(data.ids[i].to_id); +} +} +localStorage.who_to_follow = JSON.stringify(wtflist); +} +setWhoToFollow(); +}).fail(function(xhr) { +if(xhr.readyState == 0) { +setWhoToFollow(); +} +}); +} +} +function addFollowProfile(id,account) { +api.get('search',[{name:'q',data:"@"+account},{name:'resolve',data:'true'}], function(search) { +if(search.accounts[0].display_name.length == 0) { +search.accounts[0].display_name = search.accounts[0].username; +} +$('.what_to_follow_'+id+' > .icon_box img').attr('src',search.accounts[0].avatar); +$('.what_to_follow_'+id+' .label_box > a').attr('href',getRelativeURL(search.accounts[0].url,search.accounts[0].id)); +$('.what_to_follow_'+id+' .label_box > a > h3 .dn').text(search.accounts[0].display_name); +$('.what_to_follow_'+id+' .label_box > a > h3 .un').text('@'+search.accounts[0].username); +$('.what_to_follow_'+id+' .label_box > .follow_button').attr('mid',search.accounts[0].id); +$('.what_to_follow_'+id+' .label_box > .follow_button').attr('data',search.accounts[0].url); +follow_loaded++; +}); +} diff --git a/assets/js/halcyon/halcyonUI.js b/assets/js/halcyon/halcyonUI.js index 41cecfc..fc64d03 100644 --- a/assets/js/halcyon/halcyonUI.js +++ b/assets/js/halcyon/halcyonUI.js @@ -211,15 +211,6 @@ return media_views; } function timeline_template(status) { if (status.reblog === null) { -if ( -status.account.id !== JSON.parse(localStorage.getItem("what_to_follow_0")).id & -status.account.id !== JSON.parse(localStorage.getItem("what_to_follow_1")).id & -status.account.id !== JSON.parse(localStorage.getItem("what_to_follow_2")).id & -status.account.id != current_id & -current_following_ids.indexOf(status.account.id) === -1 -) { -localStorage.setItem("what_to_follow_"+String(Math.floor(Math.random()*3)), JSON.stringify(status.account) ); -} for(i=0;i<status.emojis.length;i++) { status.content = status.content.replace(new RegExp(":"+status.emojis[i].shortcode+":","g"),"<img src='"+status.emojis[i].static_url+"' class='emoji'>"); } @@ -336,15 +327,6 @@ ${toot_reblog_button} </li>`); return $(html) } else { -if ( -status.reblog.account.id !== JSON.parse(localStorage.getItem("what_to_follow_0")).id & -status.reblog.account.id !== JSON.parse(localStorage.getItem("what_to_follow_1")).id & -status.reblog.account.id !== JSON.parse(localStorage.getItem("what_to_follow_2")).id & -status.reblog.account.id != current_id & -current_following_ids.indexOf(status.reblog.account.id) === -1 -) { -localStorage.setItem("what_to_follow_" + String(Math.floor(Math.random()*3)), JSON.stringify(status.reblog.account)); -} for(i=0;i<status.reblog.emojis.length;i++) { status.reblog.content = status.reblog.content.replace(new RegExp(":"+status.reblog.emojis[i].shortcode+":","g"),"<img src='"+status.reblog.emojis[i].static_url+"' class='emoji'>"); } @@ -2528,6 +2510,12 @@ putMessage("Desktop notifications disabled"); }); }) $(function() { +$("#enable_follow").click(function() { +localStorage.setItem("setting_who_to_follow","true"); +setWhoToFollow(true); +}); +}) +$(function() { shortcut.add("n",function() { $("#creat_status").click(); },{ diff --git a/config.ini.sample b/config.ini.sample index 3600bb9..a3bfcf6 100644 --- a/config.ini.sample +++ b/config.ini.sample @@ -2,4 +2,4 @@ [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}} diff --git a/footer.php b/footer.php index 597d049..32b5ab5 100644 --- a/footer.php +++ b/footer.php @@ -17,44 +17,11 @@ <?php if (isset($_GET['status'])): ?> setOverlayStatus('<?php echo $_GET['status']; ?>'); <?php endif; ?> -setCurrentProfile(); badges_update(); $('.header_settings_link').attr('href','https://'+current_instance+'/settings/preferences'); $('.footer_widget_about').attr('href','https://'+current_instance+'/about'); $('.footer_widget_instance').attr('href','https://'+current_instance+'/about/more'); $('.footer_widget_terms').attr('href','https://'+current_instance+'/terms'); -</script> -<script> -const what_to_follow_0 = JSON.parse(localStorage.getItem("what_to_follow_0")); -const what_to_follow_1 = JSON.parse(localStorage.getItem("what_to_follow_1")); -const what_to_follow_2 = JSON.parse(localStorage.getItem("what_to_follow_2")); -if(what_to_follow_0.display_name.length == 0) { -what_to_follow_0.display_name = what_to_follow_0.username; -} -if(what_to_follow_1.display_name.length == 0) { -what_to_follow_1.display_name = what_to_follow_1.username; -} -if(what_to_follow_2.display_name.length == 0) { -what_to_follow_2.display_name = what_to_follow_2.username; -} -$('.what_to_follow_0 > .icon_box img').attr('src', what_to_follow_0.avatar); -$('.what_to_follow_0 .label_box > a').attr('href', getRelativeURL(what_to_follow_0.url, what_to_follow_0.id) ); -$('.what_to_follow_0 .label_box > a > h3 .dn').text(what_to_follow_0.display_name); -$('.what_to_follow_0 .label_box > a > h3 .un').text('@'+what_to_follow_0.username); -$('.what_to_follow_0 .label_box > .follow_button').attr('mid', what_to_follow_0.id); -$('.what_to_follow_0 .label_box > .follow_button').attr('data', what_to_follow_0.url); -$('.what_to_follow_1 > .icon_box img').attr('src', what_to_follow_1.avatar); -$('.what_to_follow_1 .label_box > a').attr('href', getRelativeURL(what_to_follow_1.url, what_to_follow_1.id) ); -$('.what_to_follow_1 .label_box > a > h3 .dn').text(what_to_follow_1.display_name); -$('.what_to_follow_1 .label_box > a > h3 .un').text('@'+what_to_follow_1.username); -$('.what_to_follow_1 .label_box > .follow_button').attr('mid', what_to_follow_1.id); -$('.what_to_follow_0 .label_box > .follow_button').attr('data', what_to_follow_1.url); -$('.what_to_follow_2 > .icon_box img').attr('src', what_to_follow_2.avatar); -$('.what_to_follow_2 .label_box > a').attr('href', getRelativeURL(what_to_follow_2.url, what_to_follow_2.id) ); -$('.what_to_follow_2 .label_box > a > h3 .dn').text(what_to_follow_2.display_name); -$('.what_to_follow_2 .label_box > a > h3 .un').text('@'+what_to_follow_2.username); -$('.what_to_follow_2 .label_box > .follow_button').attr('mid', what_to_follow_2.id); -$('.what_to_follow_0 .label_box > .follow_button').attr('data', what_to_follow_2.url); replace_emoji(); </script> </body> diff --git a/login/auth.php b/login/auth.php index f3eabd3..84c5350 100644 --- a/login/auth.php +++ b/login/auth.php @@ -34,9 +34,7 @@ localStorage.setItem('setting_local_instance', 'default'); localStorage.setItem('setting_search_filter', 'all'); localStorage.setItem('setting_link_previews', 'true'); localStorage.setItem('setting_desktop_notifications', 'true'); -localStorage.setItem('what_to_follow_0', JSON.stringify({id:'',username:'Halcyon',display_name:'Halcyon for Mastodon',url:'https://social.csswg.org/@halcyon',avatar:'https://social.csswg.org/system/accounts/avatars/000/005/666/original/e9a158381ce1249a.png'})); -localStorage.setItem('what_to_follow_1', JSON.stringify({id:'',username:'Gargron',display_name:'Eugen',url:'https://mastodon.social/@Gargron',avatar:'https://files.mastodon.social/accounts/avatars/000/000/001/original/4df197532c6b768c.png'})); -localStorage.setItem('what_to_follow_2', JSON.stringify({id:'',username:'Mastodon',display_name:'Mastodon',url:'https://mastodon.social/@Mastodon',avatar:'https://files.mastodon.social/accounts/avatars/000/013/179/original/27bc451c7713091b.jpg'})); +localStorage.setItem('setting_who_to_follow', 'false'); location.href = '/'; </script> "; diff --git a/version.txt b/version.txt index e25d8d9..0664a8f 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.1.5 +1.1.6 diff --git a/widgets/side_who_to_follow.php b/widgets/side_who_to_follow.php index 9d4abbc..0e04d75 100644 --- a/widgets/side_who_to_follow.php +++ b/widgets/side_who_to_follow.php @@ -1,4 +1,27 @@ -<div class="side_widget what_to_follow"> +<?php +$appSettings = parse_ini_file('config.ini',true); +echo "<span id='who-to-follow-provider' style='display:none'>".$appSettings["App"]["who_to_follow_provider"]."</span>"; +?> +<div class="side_widget follow_opt_in side_widgets_footer"> +<h2>Who to follow</h2> +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. +<center><br/> +<button class="halcyon_button" id="enable_follow"> +<span>Enable who to follow</span> +</button> +</center> +</div> +<div class="side_widget follow_loading" style="display:none;color:#AAB8C2"> +<h2>Who to follow</h2> +<div style="height:100px"></div> +<center> +<span class="fa-stack fa-2x"> +<i class="fa fa-circle-o-notch fa-spin" id="follow_icon"></i> +</span> +</center> +<div style="height:100px"></div> +</div> +<div class="side_widget what_to_follow" style="display:none"> <h2>Who to follow</h2> <ul class="account_list"> <li class="account_box what_to_follow_0"> @@ -53,4 +76,4 @@ </div> </li> </ul> -</div> \ No newline at end of file +</div>