From 4e73a59e773f644f385b011098df6827b01a5877 Mon Sep 17 00:00:00 2001 From: qwercik Date: Mon, 31 Jul 2023 21:52:52 +0200 Subject: [PATCH] Add prototype --- forum/qa-include/lang/qa-lang-question.php | 6 ++ forum/qa-include/pages/question-submit.php | 23 ++++++ forum/qa-lang/pl/qa-lang-question.php | 6 ++ .../q2apro-history-check.php | 21 ++++- .../q2apro-onsitenotifications-layer.php | 54 +++++++++++++ .../q2apro-on-site-notifications/utils.php | 75 ++++++++++++++++++ .../SnowFlat/images/icons/mute-white.png | Bin 0 -> 445 bytes forum/qa-theme/SnowFlat/images/icons/mute.png | Bin 0 -> 407 bytes .../SnowFlat/images/icons/unmute-white.png | Bin 0 -> 326 bytes .../qa-theme/SnowFlat/images/icons/unmute.png | Bin 0 -> 318 bytes forum/qa-theme/SnowFlat/qa-styles.css | 12 +++ 11 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 forum/qa-plugin/q2apro-on-site-notifications/utils.php create mode 100644 forum/qa-theme/SnowFlat/images/icons/mute-white.png create mode 100644 forum/qa-theme/SnowFlat/images/icons/mute.png create mode 100644 forum/qa-theme/SnowFlat/images/icons/unmute-white.png create mode 100644 forum/qa-theme/SnowFlat/images/icons/unmute.png diff --git a/forum/qa-include/lang/qa-lang-question.php b/forum/qa-include/lang/qa-lang-question.php index 163a533cd..250255a09 100644 --- a/forum/qa-include/lang/qa-lang-question.php +++ b/forum/qa-include/lang/qa-lang-question.php @@ -108,6 +108,12 @@ 'flag_button' => 'flag', 'flag_c_popup' => 'Flag this comment as spam or inappropriate', 'flag_hide_button' => 'flag and hide', + + 'mute_button' => 'Mute thread', + 'mute_popup' => 'Mute this thread to not receive any further notifications', + 'unmute_button' => 'Unmute thread', + 'unmute_popup' => 'Unmute this thread to receive notifications again', + 'flag_limit' => 'Too many posts flagged - please try again in an hour', 'flag_must_confirm' => 'Please ^5confirm your email address^6 to flag posts.', 'flag_must_login' => 'Please ^1log in^2 or ^3register^4 to flag posts.', diff --git a/forum/qa-include/pages/question-submit.php b/forum/qa-include/pages/question-submit.php index a3024d9c9..713c8e008 100644 --- a/forum/qa-include/pages/question-submit.php +++ b/forum/qa-include/pages/question-submit.php @@ -39,6 +39,7 @@ function qa_page_q_single_click_q($question, $answers, $commentsfollows, $closep { require_once QA_INCLUDE_DIR.'app/post-update.php'; require_once QA_INCLUDE_DIR.'app/limits.php'; + require_once QA_PLUGIN_DIR.'/q2apro-on-site-notifications/utils.php'; $userid=qa_get_logged_in_userid(); $handle=qa_get_logged_in_handle(); @@ -49,6 +50,16 @@ function qa_page_q_single_click_q($question, $answers, $commentsfollows, $closep return true; } + if (qa_clicked('q_domute') && qa_page_q_click_check_form_code($question, $error)) { + mute_thread($userid, $question['postid']); + return true; + } + + if (qa_clicked('q_dounmute') && qa_page_q_click_check_form_code($question, $error)) { + unmute_thread($userid, $question['postid']); + return true; + } + if ( (qa_clicked('q_dohide') && $question['hideable']) || (qa_clicked('q_doreject') && $question['moderatable']) ) if (qa_page_q_click_check_form_code($question, $error)) { qa_question_set_hidden($question, true, $userid, $handle, $cookieid, $answers, $commentsfollows, $closepost); @@ -123,6 +134,8 @@ function qa_page_q_single_click_a($answer, $question, $answers, $commentsfollows If there is an error to display, it will be passed out in $error. */ { + require_once QA_PLUGIN_DIR.'/q2apro-on-site-notifications/utils.php'; + $userid=qa_get_logged_in_userid(); $handle=qa_get_logged_in_handle(); $cookieid=qa_cookie_get(); @@ -141,6 +154,16 @@ function qa_page_q_single_click_a($answer, $question, $answers, $commentsfollows return true; } + if (qa_clicked($prefix . 'domute') && qa_page_q_click_check_form_code($answer, $error)) { + mute_thread($userid, $answer['postid']); + return true; + } + + if (qa_clicked($prefix . 'dounmute') && qa_page_q_click_check_form_code($answer, $error)) { + unmute_thread($userid, $answer['postid']); + return true; + } + if ( (qa_clicked($prefix.'dohide') && $answer['hideable']) || (qa_clicked($prefix.'doreject') && $answer['moderatable']) ) if (qa_page_q_click_check_form_code($answer, $error)) { qa_answer_set_hidden($answer, true, $userid, $handle, $cookieid, $question, $commentsfollows); diff --git a/forum/qa-lang/pl/qa-lang-question.php b/forum/qa-lang/pl/qa-lang-question.php index b372c599e..291dc4ae2 100644 --- a/forum/qa-lang/pl/qa-lang-question.php +++ b/forum/qa-lang/pl/qa-lang-question.php @@ -96,6 +96,12 @@ 'flag_button' => 'zgłoś', 'flag_c_popup' => 'Zgłoś ten komentarz jako spam lub niezgodny z regulaminem', 'flag_hide_button' => 'zgłoś i ukryj', + + 'mute_button' => 'Wycisz wątek', + 'mute_popup' => 'Wycisz ten wątek, aby nie otrzymywać dalszych powiadomień', + 'unmute_button' => 'Subskrybuj wątek', + 'unmute_popup' => 'Subskrybuj wątek, aby ponownie otrzymywać powiadomienia', + 'flag_limit' => 'Zbyt wiele zgłoszeń. Spróbuj ponownie za godzinę', 'flag_must_confirm' => '^5Potwierdź swój adres email^6, aby móc zgłaszać treść.', 'flag_must_login' => '^1Zaloguj^2 lub ^3zarejestruj się^4, aby móc zgłaszać treść.', diff --git a/forum/qa-plugin/q2apro-on-site-notifications/q2apro-history-check.php b/forum/qa-plugin/q2apro-on-site-notifications/q2apro-history-check.php index 9dcbedb69..5145ca2f2 100644 --- a/forum/qa-plugin/q2apro-on-site-notifications/q2apro-history-check.php +++ b/forum/qa-plugin/q2apro-on-site-notifications/q2apro-history-check.php @@ -29,8 +29,26 @@ * Link to plugin file: https://github.com/NoahY/q2a-history/blob/master/qa-history-check.php */ +require_once __DIR__ . '/utils.php'; + class q2apro_history_check { + public function init_queries($tableslc) + { + $queries = []; + + if (!in_array(qa_db_add_table_prefix('muted_threads'), $tableslc)) { + $queries[] = 'CREATE TABLE IF NOT EXISTS ^muted_threads ( + postid bigint(20) unsigned NOT NULL, + userid bigint(20) unsigned NOT NULL, + KEY postid (postid), + KEY userid (userid) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8'; + } + + return $queries; + } + function process_event($event, $userid, $handle, $cookieid, $params) { if (!qa_opt('event_logger_to_database')) { @@ -139,11 +157,12 @@ private function handle_comments_thread($cookieId, $params) $commentsQuery = qa_db_query_sub('SELECT DISTINCT userid FROM `^posts` WHERE `parentid` = # AND `type` = "C" AND `userid` IS NOT NULL', $params['parentid']); + $muteChecker = new ThreadMuteChecker($params['parentid']); while (($comment = qa_db_read_one_assoc($commentsQuery, true)) !== null) { $commentUserId = $comment['userid']; // don't inform user that comments, and don't inform user that comments on his own question/answer - if ($commentUserId != $postUserId && $commentUserId != $parentUserId) { + if ($commentUserId != $postUserId && $commentUserId != $parentUserId && !$muteChecker->hasUserMutedThread($commentUserId)) { $commentUserHandle = qa_userid_to_handle($commentUserId); qa_db_query_sub( diff --git a/forum/qa-plugin/q2apro-on-site-notifications/q2apro-onsitenotifications-layer.php b/forum/qa-plugin/q2apro-on-site-notifications/q2apro-onsitenotifications-layer.php index b731ccc46..8bde830d9 100644 --- a/forum/qa-plugin/q2apro-on-site-notifications/q2apro-onsitenotifications-layer.php +++ b/forum/qa-plugin/q2apro-on-site-notifications/q2apro-onsitenotifications-layer.php @@ -157,6 +157,60 @@ function doctype() { qa_html_theme_base::doctype(); } + public function a_item_buttons($a_item) + { + if (!empty($a_item['form'])) { + $answerId = $a_item['raw']['postid']; + $questionId = $a_item['raw']['parentid']; + + $this->addCustomButtons( + $a_item, + 'a' . $a_item['raw']['postid'], + ' onclick="return qa_answer_click('.qa_js($answerId).', '.qa_js($questionId).', this);"' + ); + } + + return parent::a_item_buttons($a_item); + } + + public function q_view_buttons($q_view) + { + if (!empty($q_view['form'])) { + $this->addCustomButtons( + $q_view, + 'q', + ' onclick="qa_show_waiting_after(this, false);"' + ); + } + + return parent::q_view_buttons($q_view); + } + + protected function addCustomButtons(&$view, $prefix, $clicksuffix) + { + require_once __DIR__ . '/../qa-plugin/q2apro-on-site-notifications/utils.php'; + + $current_user_id = qa_get_logged_in_userid(); + if ($current_user_id === null) { + return; + } + + $postId = $view['raw']['postid']; + $participantsObtainer = new ThreadParticipantsObtainer($postId); + if (!$participantsObtainer->isParticipant($current_user_id)) { + return; + } + + $muteChecker = new ThreadMuteChecker($postId); + $muted = $muteChecker->hasUserMutedThread($current_user_id); + $action = $muted ? 'unmute' : 'mute'; + $view['form']['buttons'][$action]=array( + 'tags' => "name=\"{$prefix}_do{$action}\"" . $clicksuffix, + 'label' => qa_lang_html("question/{$action}_button"), + 'popup' => qa_lang_html("question/{$action}_popup"), + ); + } + } // end qa_html_theme_layer /* diff --git a/forum/qa-plugin/q2apro-on-site-notifications/utils.php b/forum/qa-plugin/q2apro-on-site-notifications/utils.php new file mode 100644 index 000000000..5fac495e2 --- /dev/null +++ b/forum/qa-plugin/q2apro-on-site-notifications/utils.php @@ -0,0 +1,75 @@ +muted_users = $this->getUsersWhoMutedThread($postid); + } + + public function hasUserMutedThread(int $userid) + { + if (!isset($this->cache[$userid])) { + $this->cache[$userid] = in_array($userid, $this->muted_users); + } + + return $this->cache[$userid]; + } + + protected function getUsersWhoMutedThread(int $postid) + { + return qa_db_read_all_values( + qa_db_query_sub('SELECT userid FROM ^muted_threads + WHERE postid = # + ', $postid), + ); + } +} + +class ThreadParticipantsObtainer +{ + public $participants; + + public function __construct(int $postid) + { + $this->participants = $this->getThreadParticipants($postid); + } + + public function isParticipant(int $userid) + { + return in_array("$userid", $this->participants); + } + + protected function getThreadParticipants(int $postid) + { + $query = implode(' UNION ', [ + 'SELECT userid FROM ^posts WHERE postid = #', + 'SELECT DISTINCT userid FROM ^posts WHERE parentid = #', + ]); + + return qa_db_read_all_values( + qa_db_query_sub($query, $postid, $postid), + ); + } +} + +function mute_thread(int $userid, int $postid) +{ + qa_db_query_sub( + "INSERT INTO ^muted_threads (userid, postid) VALUES (#, #)", + $userid, + $postid + ); +} + +function unmute_thread(int $userid, int $postid) +{ + qa_db_query_sub( + "DELETE FROM ^muted_threads WHERE userid = # AND postid = #", + $userid, + $postid + ); +} diff --git a/forum/qa-theme/SnowFlat/images/icons/mute-white.png b/forum/qa-theme/SnowFlat/images/icons/mute-white.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca31749e3fdf0a9a7e0b75dfd4e41fc56eb7521 GIT binary patch literal 445 zcmV;u0Yd(XP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10ZK_k zK~yM_jgmi0+ffvTpHtFOONdCJ5phw+(#3$A5O8Y2A_WEMB1mRGfK#D+KSY-<9U=}z z(2|(ypi2iQ2aD3FSp?BZ9*5lc=k^!ccf0RWSJ>ALV(!XiMEx zpWgF^)eqijSuN#ks3X8P-~xCHi~>K>xdjXXb>JL$9TC6s?iID2MjTe>)yG->RXr-2 z0QH%As2-@#3-Yr1TV3pXw~L5~OP~u(0^il@gZD*T0BvCUFF2_JtOGxRmO7s0e}Iue zFu*mi0_*`Db*i9dAWTGD1FOIWu&ciOZ#Z2bum*eqw$)ca6Syh_)IGIP;D1!RYE3Qo z{Zb02fH|NF%&L*`r@$Go4ZNYZ4qS3lnXEjQX!Kd@?$00000NkvXXu0mjfGaS4s literal 0 HcmV?d00001 diff --git a/forum/qa-theme/SnowFlat/images/icons/mute.png b/forum/qa-theme/SnowFlat/images/icons/mute.png new file mode 100644 index 0000000000000000000000000000000000000000..b4f216ee4d7f1389e417357805e02ed4c177169d GIT binary patch literal 407 zcmV;I0cie-P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10VGL8 zK~y-6jnmC4MNt^W@gGMKN6J84C8<8?$ zWFkpE(h-BboX*+py?IBg{k-pgJ?mL(lU)U@qdlvs4_nA5XuJ5vMi!tEr?@~<_%?`R zduT#Xk@;|&LB#suzzy9SJ+7U$?rb5e<%sjGuL}BR)^U1+@;!Q+4&ikKG#d!{nDVp(4z;J3c8i0uF=r1Yst6GT}o1=t}b zaVyH;Uw~i8au_anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt-25T^vI!dhbrs^>z-FX`jEj zdS~XvEmq>w&oEznbZF6h#}?JgpZ4``+o+|Xws_N~MR(Pj9v!L?`?jdB`rM9Edy9ex z-@n=GPiVLmX07RaYR+o;SN*rvWZ4C+|9f<9RoJq%Q)l=$vOnN{!K8jb*&s;2%vAi< zYAcP0Rj-!c@?e!&ou4K4@cq@gR~+pJR9X!BOKh0`>y=n9U`V?t_^^6uCtJudIhK~M zZhIMT9bo(*a&dbD&kUyLiY?#&@LRIwX-`=mm;H0;)#+Dvtr6J6xngDbtAMq~OStF# WYH?hfSM&tvJqAx#KbLh*2~7ZACW#FI literal 0 HcmV?d00001 diff --git a/forum/qa-theme/SnowFlat/images/icons/unmute.png b/forum/qa-theme/SnowFlat/images/icons/unmute.png new file mode 100644 index 0000000000000000000000000000000000000000..f82526020ee33059666c3ee3e182801b5069bf4e GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5he4R}c>anMprB-l zYeY$Kep*R+Vo@qXd3m{BW?pu2a$-TMUVc&f>~}U&Kt-oLT^vI!dhcG^=*8?P!1lnu z_>Sh~ymq)@pHf##H#F2F1k{{DVl?fSz(K5&1wq?so zL_GWdeg4h4^GoJD%Hda+k`%kK@bZ@;@$w(MmIoK~RYU|^9~Z7GXtbMG*uT1VZtqFr}bb>C*89}UOZ&IaFhN_^Qr;kseanZgf}AIk3}1-t)Z4*99@Nti$LFVI^I Mp00i_>zopr0M!(NX8-^I literal 0 HcmV?d00001 diff --git a/forum/qa-theme/SnowFlat/qa-styles.css b/forum/qa-theme/SnowFlat/qa-styles.css index 9051bbaef..1ae99c558 100644 --- a/forum/qa-theme/SnowFlat/qa-styles.css +++ b/forum/qa-theme/SnowFlat/qa-styles.css @@ -2338,6 +2338,12 @@ input[type="submit"], button { .qa-form-light-button-unflag, .qa-form-light-button-clearflags { background-image: url('images/icons/un-flag-white.png'); } +.qa-form-light-button-mute { + background-image: url('images/icons/mute-white.png'); +} +.qa-form-light-button-unmute { + background-image: url('images/icons/unmute-white.png'); +} .qa-form-light-button-hide { background-image: url('images/icons/hide-white.png'); } @@ -2856,6 +2862,12 @@ input[type="submit"], button { .qa-c-list-item .qa-form-light-button-unflag, .qa-c-list-item .qa-form-light-button-clearflags { background-image: url('images/icons/un-flag.png'); } +.qa-c-list-item .qa-form-light-button-mute { + background-image: url('images/icons/mute.png'); +} +.qa-c-list-item .qa-form-light-button-unmute { + background-image: url('images/icons/unmute.png'); +} .qa-c-list-item .qa-form-light-button-hide { background-image: url('images/icons/hide.png'); }