From 9f029336cab322e04d29af842ba0a666189c8683 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 11 Feb 2020 09:20:32 +0000 Subject: fix notifications for polls --- Zotlabs/Lib/Enotify.php | 5 +++-- Zotlabs/Lib/ThreadItem.php | 4 ++++ include/conversation.php | 25 ++++++++++++++++++------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index f6f8ad0cb..85e90d67c 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -810,8 +810,9 @@ class Enotify { } else { $itemem_text = (($item['item_thread_top']) - ? t('created a new post') - : sprintf( t('commented on %s\'s post'), '[bdi]' . $item['owner']['xchan_name'] . '[/bdi]')); + ? (($item['obj_type'] === 'Question') ? t('created a new poll') : t('created a new post')) + : (($item['obj_type'] === 'Answer') ? sprintf( t('voted on %s\'s poll'), '[bdi]' . $item['owner']['xchan_name'] . '[/bdi]') : sprintf( t('commented on %s\'s post'), '[bdi]' . $item['owner']['xchan_name'] . '[/bdi]')) + ); if($item['verb'] === ACTIVITY_SHARE) { $itemem_text = sprintf( t('repeated %s\'s post'), '[bdi]' . $item['author']['xchan_name'] . '[/bdi]'); diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 2386a1f0d..dee7cda56 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -204,6 +204,10 @@ class ThreadItem { } } + if($item['obj_type'] === 'Question') { + $response_verbs[] = 'answer'; + } + $consensus = (intval($item['item_consensus']) ? true : false); if($consensus) { $response_verbs[] = 'agree'; diff --git a/include/conversation.php b/include/conversation.php index 327d89e53..0098a694d 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -625,11 +625,17 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa $items = $cb['items']; - $conv_responses = array( - 'like' => array('title' => t('Likes','title')),'dislike' => array('title' => t('Dislikes','title')), - 'agree' => array('title' => t('Agree','title')),'disagree' => array('title' => t('Disagree','title')), 'abstain' => array('title' => t('Abstain','title')), - 'attendyes' => array('title' => t('Attending','title')), 'attendno' => array('title' => t('Not attending','title')), 'attendmaybe' => array('title' => t('Might attend','title')) - ); + $conv_responses = [ + 'like' => ['title' => t('Likes','title')], + 'dislike' => ['title' => t('Dislikes','title')], + 'agree' => ['title' => t('Agree','title')], + 'disagree' => ['title' => t('Disagree','title')], + 'abstain' => ['title' => t('Abstain','title')], + 'attendyes' => ['title' => t('Attending','title')], + 'attendno' => ['title' => t('Not attending','title')], + 'attendmaybe' => ['title' => t('Might attend','title')], + 'answer' => [] + ]; // array with html for each thread (parent+comments) @@ -1136,7 +1142,7 @@ function builtin_activity_puller($item, &$conv_responses) { // if this item is a post or comment there's nothing for us to do here, just return. - if(activity_match($item['verb'],ACTIVITY_POST)) + if(activity_match($item['verb'],ACTIVITY_POST) && $item['obj_type'] !== 'Answer') return; foreach($conv_responses as $mode => $v) { @@ -1168,6 +1174,9 @@ function builtin_activity_puller($item, &$conv_responses) { case 'attendmaybe': $verb = ACTIVITY_ATTENDMAYBE; break; + case 'answer': + $verb = ACTIVITY_POST; + break; default: return; break; @@ -1183,9 +1192,11 @@ function builtin_activity_puller($item, &$conv_responses) { if(! $item['thr_parent']) $item['thr_parent'] = $item['parent_mid']; - $conv_responses[$mode]['mids'][$item['thr_parent']][] = 'b64.' . base64url_encode($item['mid']); + if($item['obj_type'] === 'Answer') + continue; + if(! ((isset($conv_responses[$mode][$item['thr_parent'] . '-l'])) && (is_array($conv_responses[$mode][$item['thr_parent'] . '-l'])))) $conv_responses[$mode][$item['thr_parent'] . '-l'] = array(); -- cgit v1.2.3 From d5ae9aedc44db6fa226edfb4164e2cb182815372 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 13 Feb 2020 10:38:47 +0100 Subject: remove unused images --- images/article.gif | Bin 1060 -> 0 bytes images/audio.gif | Bin 559 -> 0 bytes images/b_block.gif | Bin 83 -> 0 bytes images/b_drop.gif | Bin 138 -> 0 bytes images/b_drop.png | Bin 311 -> 0 bytes images/b_drophide.gif | Bin 111 -> 0 bytes images/b_dropshow.gif | Bin 138 -> 0 bytes images/b_edit.gif | Bin 311 -> 0 bytes images/b_edit.png | Bin 451 -> 0 bytes images/bug-x.gif | Bin 134 -> 0 bytes images/calendar.png | Bin 853 -> 0 bytes images/camera-icon.gif | Bin 1015 -> 0 bytes images/checkbox-checked-32.png | Bin 1397 -> 0 bytes images/checkbox-unchecked-32.png | Bin 1063 -> 0 bytes images/connect-bg.png | Bin 689 -> 0 bytes images/content-types.png | Bin 3892 -> 0 bytes images/default-group-mm.png | Bin 598 -> 0 bytes images/document.gif | Bin 1362 -> 0 bytes images/ghash-32.png | Bin 1824 -> 0 bytes images/globe.gif | Bin 1025 -> 0 bytes images/hide_off.png | Bin 281 -> 0 bytes images/hide_on.png | Bin 277 -> 0 bytes images/hubzilla_house_arrows.png | Bin 22076 -> 0 bytes images/hz-bookmark-32.png | Bin 973 -> 0 bytes images/icons.png | Bin 12638 -> 0 bytes images/larrow.gif | Bin 211 -> 0 bytes images/larrw.gif | Bin 1004 -> 0 bytes images/link-icon.gif | Bin 145 -> 0 bytes images/lock_icon.gif | Bin 932 -> 0 bytes images/lrarrow.gif | Bin 236 -> 0 bytes images/mapicon.gif | Bin 1042 -> 0 bytes images/no.gif | Bin 631 -> 0 bytes images/noglobe.gif | Bin 606 -> 0 bytes images/nosign.jpg | Bin 6498 -> 0 bytes images/nosign.png | Bin 17868 -> 0 bytes images/onoff.jpg | Bin 502 -> 0 bytes images/pen.png | Bin 252 -> 0 bytes images/pencil.gif | Bin 553 -> 0 bytes images/penhover.png | Bin 270 -> 0 bytes images/people.gif | Bin 1478 -> 0 bytes images/plugin.png | Bin 2043 -> 0 bytes images/rarrow.gif | Bin 212 -> 0 bytes images/rarrw.gif | Bin 999 -> 0 bytes images/recycle.gif | Bin 612 -> 0 bytes images/red_antiprism.png | Bin 120847 -> 0 bytes images/red_antiprism.xcf | Bin 659160 -> 0 bytes images/redmatrix_logo.svg | 85 ------------------- images/remote-link.gif | Bin 237 -> 0 bytes images/rhash-16.png | Bin 679 -> 0 bytes images/rhash-32.png | Bin 1322 -> 0 bytes images/rhash-64.png | Bin 3115 -> 0 bytes images/rhash.xcf | Bin 94324 -> 0 bytes images/rm-16.png | Bin 676 -> 0 bytes images/rm-32.png | Bin 1186 -> 0 bytes images/rm-64.png | Bin 1897 -> 0 bytes images/rm-old.png | Bin 12441 -> 0 bytes images/rm-transparent-dark-background.png | Bin 6370 -> 0 bytes images/rm-transparent-large-old.png | Bin 42706 -> 0 bytes images/rm.png | Bin 6362 -> 0 bytes images/rm.svg | 132 ------------------------------ images/rm300.png | Bin 6426 -> 0 bytes images/rotator.gif | Bin 826 -> 0 bytes images/search_18.png | Bin 3302 -> 0 bytes images/selected.png | Bin 502 -> 0 bytes images/share.gif | Bin 155 -> 0 bytes images/show_all_off.png | Bin 539 -> 0 bytes images/show_all_on.png | Bin 464 -> 0 bytes images/show_off.png | Bin 244 -> 0 bytes images/show_on.png | Bin 218 -> 0 bytes images/spencil.gif | Bin 497 -> 0 bytes images/star.png | Bin 388 -> 0 bytes images/star_dummy.png | Bin 183 -> 0 bytes images/tag.png | Bin 528 -> 0 bytes images/tag_b.png | Bin 346 -> 0 bytes images/tools.png | Bin 490 -> 0 bytes images/unlock_icon.gif | Bin 938 -> 0 bytes images/video.gif | Bin 257 -> 0 bytes 77 files changed, 217 deletions(-) delete mode 100644 images/article.gif delete mode 100644 images/audio.gif delete mode 100644 images/b_block.gif delete mode 100644 images/b_drop.gif delete mode 100644 images/b_drop.png delete mode 100644 images/b_drophide.gif delete mode 100644 images/b_dropshow.gif delete mode 100644 images/b_edit.gif delete mode 100644 images/b_edit.png delete mode 100644 images/bug-x.gif delete mode 100644 images/calendar.png delete mode 100644 images/camera-icon.gif delete mode 100644 images/checkbox-checked-32.png delete mode 100644 images/checkbox-unchecked-32.png delete mode 100644 images/connect-bg.png delete mode 100644 images/content-types.png delete mode 100644 images/default-group-mm.png delete mode 100644 images/document.gif delete mode 100644 images/ghash-32.png delete mode 100644 images/globe.gif delete mode 100644 images/hide_off.png delete mode 100644 images/hide_on.png delete mode 100644 images/hubzilla_house_arrows.png delete mode 100644 images/hz-bookmark-32.png delete mode 100644 images/icons.png delete mode 100644 images/larrow.gif delete mode 100644 images/larrw.gif delete mode 100644 images/link-icon.gif delete mode 100644 images/lock_icon.gif delete mode 100644 images/lrarrow.gif delete mode 100644 images/mapicon.gif delete mode 100644 images/no.gif delete mode 100644 images/noglobe.gif delete mode 100644 images/nosign.jpg delete mode 100644 images/nosign.png delete mode 100644 images/onoff.jpg delete mode 100644 images/pen.png delete mode 100644 images/pencil.gif delete mode 100644 images/penhover.png delete mode 100644 images/people.gif delete mode 100644 images/plugin.png delete mode 100644 images/rarrow.gif delete mode 100644 images/rarrw.gif delete mode 100644 images/recycle.gif delete mode 100644 images/red_antiprism.png delete mode 100644 images/red_antiprism.xcf delete mode 100644 images/redmatrix_logo.svg delete mode 100644 images/remote-link.gif delete mode 100644 images/rhash-16.png delete mode 100644 images/rhash-32.png delete mode 100644 images/rhash-64.png delete mode 100644 images/rhash.xcf delete mode 100644 images/rm-16.png delete mode 100644 images/rm-32.png delete mode 100644 images/rm-64.png delete mode 100644 images/rm-old.png delete mode 100644 images/rm-transparent-dark-background.png delete mode 100644 images/rm-transparent-large-old.png delete mode 100644 images/rm.png delete mode 100644 images/rm.svg delete mode 100644 images/rm300.png delete mode 100644 images/rotator.gif delete mode 100644 images/search_18.png delete mode 100644 images/selected.png delete mode 100644 images/share.gif delete mode 100644 images/show_all_off.png delete mode 100644 images/show_all_on.png delete mode 100644 images/show_off.png delete mode 100644 images/show_on.png delete mode 100644 images/spencil.gif delete mode 100644 images/star.png delete mode 100644 images/star_dummy.png delete mode 100644 images/tag.png delete mode 100644 images/tag_b.png delete mode 100644 images/tools.png delete mode 100644 images/unlock_icon.gif delete mode 100644 images/video.gif diff --git a/images/article.gif b/images/article.gif deleted file mode 100644 index 91aeef000..000000000 Binary files a/images/article.gif and /dev/null differ diff --git a/images/audio.gif b/images/audio.gif deleted file mode 100644 index 4be977116..000000000 Binary files a/images/audio.gif and /dev/null differ diff --git a/images/b_block.gif b/images/b_block.gif deleted file mode 100644 index 3bc7c056b..000000000 Binary files a/images/b_block.gif and /dev/null differ diff --git a/images/b_drop.gif b/images/b_drop.gif deleted file mode 100644 index b08c68b62..000000000 Binary files a/images/b_drop.gif and /dev/null differ diff --git a/images/b_drop.png b/images/b_drop.png deleted file mode 100644 index 6fc4d3b20..000000000 Binary files a/images/b_drop.png and /dev/null differ diff --git a/images/b_drophide.gif b/images/b_drophide.gif deleted file mode 100644 index 1207a935b..000000000 Binary files a/images/b_drophide.gif and /dev/null differ diff --git a/images/b_dropshow.gif b/images/b_dropshow.gif deleted file mode 100644 index b08c68b62..000000000 Binary files a/images/b_dropshow.gif and /dev/null differ diff --git a/images/b_edit.gif b/images/b_edit.gif deleted file mode 100644 index 79cb3c144..000000000 Binary files a/images/b_edit.gif and /dev/null differ diff --git a/images/b_edit.png b/images/b_edit.png deleted file mode 100644 index 05711a094..000000000 Binary files a/images/b_edit.png and /dev/null differ diff --git a/images/bug-x.gif b/images/bug-x.gif deleted file mode 100644 index 10936caa7..000000000 Binary files a/images/bug-x.gif and /dev/null differ diff --git a/images/calendar.png b/images/calendar.png deleted file mode 100644 index fbf52933d..000000000 Binary files a/images/calendar.png and /dev/null differ diff --git a/images/camera-icon.gif b/images/camera-icon.gif deleted file mode 100644 index a4adf9adf..000000000 Binary files a/images/camera-icon.gif and /dev/null differ diff --git a/images/checkbox-checked-32.png b/images/checkbox-checked-32.png deleted file mode 100644 index 01e51c203..000000000 Binary files a/images/checkbox-checked-32.png and /dev/null differ diff --git a/images/checkbox-unchecked-32.png b/images/checkbox-unchecked-32.png deleted file mode 100644 index 80ce92243..000000000 Binary files a/images/checkbox-unchecked-32.png and /dev/null differ diff --git a/images/connect-bg.png b/images/connect-bg.png deleted file mode 100644 index 0611c73e5..000000000 Binary files a/images/connect-bg.png and /dev/null differ diff --git a/images/content-types.png b/images/content-types.png deleted file mode 100644 index e46eba610..000000000 Binary files a/images/content-types.png and /dev/null differ diff --git a/images/default-group-mm.png b/images/default-group-mm.png deleted file mode 100644 index bfc8b335a..000000000 Binary files a/images/default-group-mm.png and /dev/null differ diff --git a/images/document.gif b/images/document.gif deleted file mode 100644 index 02d940968..000000000 Binary files a/images/document.gif and /dev/null differ diff --git a/images/ghash-32.png b/images/ghash-32.png deleted file mode 100644 index 6b4913b82..000000000 Binary files a/images/ghash-32.png and /dev/null differ diff --git a/images/globe.gif b/images/globe.gif deleted file mode 100644 index 3f17c5d32..000000000 Binary files a/images/globe.gif and /dev/null differ diff --git a/images/hide_off.png b/images/hide_off.png deleted file mode 100644 index d504ca2e2..000000000 Binary files a/images/hide_off.png and /dev/null differ diff --git a/images/hide_on.png b/images/hide_on.png deleted file mode 100644 index 960744c06..000000000 Binary files a/images/hide_on.png and /dev/null differ diff --git a/images/hubzilla_house_arrows.png b/images/hubzilla_house_arrows.png deleted file mode 100644 index 56402a96b..000000000 Binary files a/images/hubzilla_house_arrows.png and /dev/null differ diff --git a/images/hz-bookmark-32.png b/images/hz-bookmark-32.png deleted file mode 100644 index f3a09d9b4..000000000 Binary files a/images/hz-bookmark-32.png and /dev/null differ diff --git a/images/icons.png b/images/icons.png deleted file mode 100644 index 34d77a136..000000000 Binary files a/images/icons.png and /dev/null differ diff --git a/images/larrow.gif b/images/larrow.gif deleted file mode 100644 index ab08bb57e..000000000 Binary files a/images/larrow.gif and /dev/null differ diff --git a/images/larrw.gif b/images/larrw.gif deleted file mode 100644 index 08902d772..000000000 Binary files a/images/larrw.gif and /dev/null differ diff --git a/images/link-icon.gif b/images/link-icon.gif deleted file mode 100644 index c012d716e..000000000 Binary files a/images/link-icon.gif and /dev/null differ diff --git a/images/lock_icon.gif b/images/lock_icon.gif deleted file mode 100644 index b6b1b7fed..000000000 Binary files a/images/lock_icon.gif and /dev/null differ diff --git a/images/lrarrow.gif b/images/lrarrow.gif deleted file mode 100644 index fa2676944..000000000 Binary files a/images/lrarrow.gif and /dev/null differ diff --git a/images/mapicon.gif b/images/mapicon.gif deleted file mode 100644 index dd20c209b..000000000 Binary files a/images/mapicon.gif and /dev/null differ diff --git a/images/no.gif b/images/no.gif deleted file mode 100644 index eb0f2b0e9..000000000 Binary files a/images/no.gif and /dev/null differ diff --git a/images/noglobe.gif b/images/noglobe.gif deleted file mode 100644 index 81e176567..000000000 Binary files a/images/noglobe.gif and /dev/null differ diff --git a/images/nosign.jpg b/images/nosign.jpg deleted file mode 100644 index b73629332..000000000 Binary files a/images/nosign.jpg and /dev/null differ diff --git a/images/nosign.png b/images/nosign.png deleted file mode 100644 index 773c9514d..000000000 Binary files a/images/nosign.png and /dev/null differ diff --git a/images/onoff.jpg b/images/onoff.jpg deleted file mode 100644 index 7884912a7..000000000 Binary files a/images/onoff.jpg and /dev/null differ diff --git a/images/pen.png b/images/pen.png deleted file mode 100644 index 46b404941..000000000 Binary files a/images/pen.png and /dev/null differ diff --git a/images/pencil.gif b/images/pencil.gif deleted file mode 100644 index 26bfb0c9a..000000000 Binary files a/images/pencil.gif and /dev/null differ diff --git a/images/penhover.png b/images/penhover.png deleted file mode 100644 index be48d77b4..000000000 Binary files a/images/penhover.png and /dev/null differ diff --git a/images/people.gif b/images/people.gif deleted file mode 100644 index cac31db2a..000000000 Binary files a/images/people.gif and /dev/null differ diff --git a/images/plugin.png b/images/plugin.png deleted file mode 100644 index 08b09e060..000000000 Binary files a/images/plugin.png and /dev/null differ diff --git a/images/rarrow.gif b/images/rarrow.gif deleted file mode 100644 index a2d5df3e9..000000000 Binary files a/images/rarrow.gif and /dev/null differ diff --git a/images/rarrw.gif b/images/rarrw.gif deleted file mode 100644 index 849238c2d..000000000 Binary files a/images/rarrw.gif and /dev/null differ diff --git a/images/recycle.gif b/images/recycle.gif deleted file mode 100644 index 01b3e13b4..000000000 Binary files a/images/recycle.gif and /dev/null differ diff --git a/images/red_antiprism.png b/images/red_antiprism.png deleted file mode 100644 index 80637adf5..000000000 Binary files a/images/red_antiprism.png and /dev/null differ diff --git a/images/red_antiprism.xcf b/images/red_antiprism.xcf deleted file mode 100644 index bd3dd826c..000000000 Binary files a/images/red_antiprism.xcf and /dev/null differ diff --git a/images/redmatrix_logo.svg b/images/redmatrix_logo.svg deleted file mode 100644 index 840c3e624..000000000 --- a/images/redmatrix_logo.svg +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/images/remote-link.gif b/images/remote-link.gif deleted file mode 100644 index 64de29aee..000000000 Binary files a/images/remote-link.gif and /dev/null differ diff --git a/images/rhash-16.png b/images/rhash-16.png deleted file mode 100644 index 23dd9e4b3..000000000 Binary files a/images/rhash-16.png and /dev/null differ diff --git a/images/rhash-32.png b/images/rhash-32.png deleted file mode 100644 index 564556d48..000000000 Binary files a/images/rhash-32.png and /dev/null differ diff --git a/images/rhash-64.png b/images/rhash-64.png deleted file mode 100644 index 2e8396760..000000000 Binary files a/images/rhash-64.png and /dev/null differ diff --git a/images/rhash.xcf b/images/rhash.xcf deleted file mode 100644 index 960552290..000000000 Binary files a/images/rhash.xcf and /dev/null differ diff --git a/images/rm-16.png b/images/rm-16.png deleted file mode 100644 index 9361ef2b7..000000000 Binary files a/images/rm-16.png and /dev/null differ diff --git a/images/rm-32.png b/images/rm-32.png deleted file mode 100644 index 8416edd97..000000000 Binary files a/images/rm-32.png and /dev/null differ diff --git a/images/rm-64.png b/images/rm-64.png deleted file mode 100644 index 8021f9d55..000000000 Binary files a/images/rm-64.png and /dev/null differ diff --git a/images/rm-old.png b/images/rm-old.png deleted file mode 100644 index 29caaf3f6..000000000 Binary files a/images/rm-old.png and /dev/null differ diff --git a/images/rm-transparent-dark-background.png b/images/rm-transparent-dark-background.png deleted file mode 100644 index 7f94ccdd9..000000000 Binary files a/images/rm-transparent-dark-background.png and /dev/null differ diff --git a/images/rm-transparent-large-old.png b/images/rm-transparent-large-old.png deleted file mode 100644 index 8844af8f0..000000000 Binary files a/images/rm-transparent-large-old.png and /dev/null differ diff --git a/images/rm.png b/images/rm.png deleted file mode 100644 index 99ef21328..000000000 Binary files a/images/rm.png and /dev/null differ diff --git a/images/rm.svg b/images/rm.svg deleted file mode 100644 index c056a621e..000000000 --- a/images/rm.svg +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/images/rm300.png b/images/rm300.png deleted file mode 100644 index bc2600348..000000000 Binary files a/images/rm300.png and /dev/null differ diff --git a/images/rotator.gif b/images/rotator.gif deleted file mode 100644 index 3797ec3e4..000000000 Binary files a/images/rotator.gif and /dev/null differ diff --git a/images/search_18.png b/images/search_18.png deleted file mode 100644 index 539739670..000000000 Binary files a/images/search_18.png and /dev/null differ diff --git a/images/selected.png b/images/selected.png deleted file mode 100644 index 79a7c77c6..000000000 Binary files a/images/selected.png and /dev/null differ diff --git a/images/share.gif b/images/share.gif deleted file mode 100644 index 035fa2e38..000000000 Binary files a/images/share.gif and /dev/null differ diff --git a/images/show_all_off.png b/images/show_all_off.png deleted file mode 100644 index cc96d28f0..000000000 Binary files a/images/show_all_off.png and /dev/null differ diff --git a/images/show_all_on.png b/images/show_all_on.png deleted file mode 100644 index 87a7710b5..000000000 Binary files a/images/show_all_on.png and /dev/null differ diff --git a/images/show_off.png b/images/show_off.png deleted file mode 100644 index 4bcf47123..000000000 Binary files a/images/show_off.png and /dev/null differ diff --git a/images/show_on.png b/images/show_on.png deleted file mode 100644 index b8d1f5bac..000000000 Binary files a/images/show_on.png and /dev/null differ diff --git a/images/spencil.gif b/images/spencil.gif deleted file mode 100644 index 0a2551ac0..000000000 Binary files a/images/spencil.gif and /dev/null differ diff --git a/images/star.png b/images/star.png deleted file mode 100644 index 0b00cb189..000000000 Binary files a/images/star.png and /dev/null differ diff --git a/images/star_dummy.png b/images/star_dummy.png deleted file mode 100644 index ce11f30d4..000000000 Binary files a/images/star_dummy.png and /dev/null differ diff --git a/images/tag.png b/images/tag.png deleted file mode 100644 index 40c5fd44e..000000000 Binary files a/images/tag.png and /dev/null differ diff --git a/images/tag_b.png b/images/tag_b.png deleted file mode 100644 index 66c03415d..000000000 Binary files a/images/tag_b.png and /dev/null differ diff --git a/images/tools.png b/images/tools.png deleted file mode 100644 index c17094a81..000000000 Binary files a/images/tools.png and /dev/null differ diff --git a/images/unlock_icon.gif b/images/unlock_icon.gif deleted file mode 100644 index 254ac8bfd..000000000 Binary files a/images/unlock_icon.gif and /dev/null differ diff --git a/images/video.gif b/images/video.gif deleted file mode 100644 index e4d5e8cdd..000000000 Binary files a/images/video.gif and /dev/null differ -- cgit v1.2.3 From 7d05b8e5fdcf628f6badaff60c73811dcc19e45c Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 20 Feb 2020 17:16:14 +0000 Subject: vote issue --- Zotlabs/Module/Vote.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Zotlabs/Module/Vote.php b/Zotlabs/Module/Vote.php index e1932da23..d67a6f176 100644 --- a/Zotlabs/Module/Vote.php +++ b/Zotlabs/Module/Vote.php @@ -83,7 +83,7 @@ class Vote extends Controller { $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; - $item['item_origin'] = true; + $item['item_origin'] = 1; $item['parent'] = $fetch[0]['id']; $item['parent_mid'] = $fetch[0]['mid']; $item['thr_parent'] = $fetch[0]['mid']; @@ -93,6 +93,9 @@ class Vote extends Controller { $item['title'] = $res; $item['author_xchan'] = $channel['channel_hash']; $item['owner_xchan'] = $fetch[0]['author_xchan']; + $item['allow_cid'] = '<' . $fetch[0]['author_xchan'] . '>'; + $item['item_private'] = 1; + $item['obj_type'] = 'Note'; $item['author'] = channelx_by_n($channel['channel_id']); -- cgit v1.2.3 From b7bac45427a400275597faa9b51c4d277fe1f5c7 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Thu, 20 Feb 2020 20:03:50 +0100 Subject: Revert "Use argv() instead URI parsing" This reverts commit bcfb69eeeef6a0506a0ec0574a03b673df84a55a --- Zotlabs/Lib/Libsync.php | 5 +- Zotlabs/Module/Cdav.php | 417 +++++++++++++++++++++--------------------------- include/cdav.php | 186 +++++++++++++++++++++ include/import.php | 67 ++++++++ include/zot.php | 3 + 5 files changed, 443 insertions(+), 235 deletions(-) create mode 100644 include/cdav.php diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index b9e9bb38a..d1756cf47 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -244,7 +244,10 @@ class Libsync { if(array_key_exists('app',$arr) && $arr['app']) sync_apps($channel,$arr['app']); - + + if(array_key_exists('addressbook',$arr) && $arr['addressbook']) + sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index af40689c1..593a78a53 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -10,6 +10,7 @@ require_once('include/event.php'); require_once('include/auth.php'); require_once('include/security.php'); +require_once('include/cdav.php'); class Cdav extends Controller { @@ -156,6 +157,69 @@ class Cdav extends Controller { } } + + // Track CDAV updates from remote clients + + $httpmethod = $_SERVER['REQUEST_METHOD']; + + if($httpmethod === 'PUT' || $httpmethod === 'DELETE') { + + $httpuri = $_SERVER['REQUEST_URI']; + + logger("debug: method: " . $httpmethod, LOGGER_DEBUG); + logger("debug: uri: " . $httpuri, LOGGER_DEBUG); + + // currently we process CardDAV requests only + if(strpos($httpuri, 'cdav/addressbooks')) { + + $uri = basename($httpuri); + $httpbody = file_get_contents('php://input'); + + logger("debug: body: " . $httpbody, LOGGER_DEBUG); + + if($id = get_cdav_id($principalUri, explode("/", $httpuri)[4], 'addressbooks')) { + + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + + $etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false); + + // delete + if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag) + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'delete_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri + ] + ]); + else { + if($etag) { + // update + if($cdavdata['etag'] !== $etag) + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'update_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri, + 'card' => $httpbody + ] + ]); + } + else { + // new + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'import', + 'uri' => $cdavdata['uri'], + 'ids' => [ $uri ], + 'card' => $httpbody + ] + ]); + } + } + } + } + } $principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo); @@ -523,6 +587,14 @@ class Cdav extends Controller { $properties = ['{DAV:}displayname' => $_REQUEST['{DAV:}displayname']]; $carddavBackend->createAddressBook($principalUri, $addressbookUri, $properties); + + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'create', + 'uri' => $addressbookUri, + 'properties' => $properties + ] + ]); } //edit addressbook @@ -530,6 +602,8 @@ class Cdav extends Controller { $id = $_REQUEST['id']; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + if(! cdav_perms($id,$addressbooks)) return; @@ -538,16 +612,24 @@ class Cdav extends Controller { ]; $patch = new \Sabre\DAV\PropPatch($mutations); - $carddavBackend->updateAddressBook($id, $patch); - $patch->commit(); + + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'edit', + 'uri' => $cdavdata['uri'], + 'mutations' => $mutations, + ] + ]); } //create addressbook card if($_REQUEST['create'] && $_REQUEST['target'] && $_REQUEST['fn']) { $id = $_REQUEST['target']; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + do { $duplicate = false; $uri = random_string(40) . '.vcf'; @@ -569,86 +651,22 @@ class Cdav extends Controller { 'N' => array_reverse(explode(' ', $fn)) ]); - $org = $_REQUEST['org']; - if($org) { - $vcard->ORG = $org; - } + $fields = $this->request_to_array($_REQUEST); - $title = $_REQUEST['title']; - if($title) { - $vcard->TITLE = $title; - } - - $tel = $_REQUEST['tel']; - $tel_type = $_REQUEST['tel_type']; - if($tel) { - $i = 0; - foreach($tel as $item) { - if($item) { - $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); - } - $i++; - } - } - - $email = $_REQUEST['email']; - $email_type = $_REQUEST['email_type']; - if($email) { - $i = 0; - foreach($email as $item) { - if($item) { - $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); - } - $i++; - } - } - - $impp = $_REQUEST['impp']; - $impp_type = $_REQUEST['impp_type']; - if($impp) { - $i = 0; - foreach($impp as $item) { - if($item) { - $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); - } - $i++; - } - } - - $url = $_REQUEST['url']; - $url_type = $_REQUEST['url_type']; - if($url) { - $i = 0; - foreach($url as $item) { - if($item) { - $vcard->add('URL', $item, ['type' => $url_type[$i]]); - } - $i++; - } - } - - $adr = $_REQUEST['adr']; - $adr_type = $_REQUEST['adr_type']; - - if($adr) { - $i = 0; - foreach($adr as $item) { - if($item) { - $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); - } - $i++; - } - } - - $note = $_REQUEST['note']; - if($note) { - $vcard->NOTE = $note; - } + process_cdav_card($fields, $vcard); $cardData = $vcard->serialize(); $carddavBackend->createCard($id, $uri, $cardData); + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'import', + 'uri' => $cdavdata['uri'], + 'ids' => [ $uri ], + 'card' => $cardData + ] + ]); } //edit addressbook card @@ -656,6 +674,8 @@ class Cdav extends Controller { $id = $_REQUEST['target']; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + if(!cdav_perms($id,$addressbooks)) return; @@ -670,113 +690,23 @@ class Cdav extends Controller { $vcard->N = array_reverse(explode(' ', $fn)); } - $org = $_REQUEST['org']; - if($org) { - $vcard->ORG = $org; - } - else { - unset($vcard->ORG); - } + $fields = $this->request_to_array($_REQUEST); - $title = $_REQUEST['title']; - if($title) { - $vcard->TITLE = $title; - } - else { - unset($vcard->TITLE); - } - - $tel = $_REQUEST['tel']; - $tel_type = $_REQUEST['tel_type']; - if($tel) { - $i = 0; - unset($vcard->TEL); - foreach($tel as $item) { - if($item) { - $vcard->add('TEL', $item, ['type' => $tel_type[$i]]); - } - $i++; - } - } - else { - unset($vcard->TEL); - } - - $email = $_REQUEST['email']; - $email_type = $_REQUEST['email_type']; - if($email) { - $i = 0; - unset($vcard->EMAIL); - foreach($email as $item) { - if($item) { - $vcard->add('EMAIL', $item, ['type' => $email_type[$i]]); - } - $i++; - } - } - else { - unset($vcard->EMAIL); - } - - $impp = $_REQUEST['impp']; - $impp_type = $_REQUEST['impp_type']; - if($impp) { - $i = 0; - unset($vcard->IMPP); - foreach($impp as $item) { - if($item) { - $vcard->add('IMPP', $item, ['type' => $impp_type[$i]]); - } - $i++; - } - } - else { - unset($vcard->IMPP); - } - - $url = $_REQUEST['url']; - $url_type = $_REQUEST['url_type']; - if($url) { - $i = 0; - unset($vcard->URL); - foreach($url as $item) { - if($item) { - $vcard->add('URL', $item, ['type' => $url_type[$i]]); - } - $i++; - } - } - else { - unset($vcard->URL); - } - - $adr = $_REQUEST['adr']; - $adr_type = $_REQUEST['adr_type']; - if($adr) { - $i = 0; - unset($vcard->ADR); - foreach($adr as $item) { - if($item) { - $vcard->add('ADR', $item, ['type' => $adr_type[$i]]); - } - $i++; - } - } - else { - unset($vcard->ADR); - } - - $note = $_REQUEST['note']; - if($note) { - $vcard->NOTE = $note; - } - else { - unset($vcard->NOTE); - } + process_cdav_card($fields, $vcard, true); $cardData = $vcard->serialize(); $carddavBackend->updateCard($id, $uri, $cardData); + + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'update_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri, + 'card' => $cardData + ] + ]); + } //delete addressbook card @@ -784,12 +714,22 @@ class Cdav extends Controller { $id = $_REQUEST['target']; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + if(!cdav_perms($id,$addressbooks)) return; $uri = $_REQUEST['uri']; $carddavBackend->deleteCard($id, $uri); + + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'delete_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri + ] + ]); } } @@ -799,6 +739,8 @@ class Cdav extends Controller { $src = $_FILES['userfile']['tmp_name']; if($src) { + + $carddata = @file_get_contents($src); if($_REQUEST['c_upload']) { if($_REQUEST['target'] == 'channel_calendar') { @@ -812,76 +754,39 @@ class Cdav extends Controller { return; } - $id = explode(':', $_REQUEST['target']); + $id = explode(':', $_REQUEST['target'])[0]; $ext = 'ics'; $table = 'calendarobjects'; $column = 'calendarid'; - $objects = new \Sabre\VObject\Splitter\ICalendar(@file_get_contents($src)); + $objects = new \Sabre\VObject\Splitter\ICalendar($carddata); $profile = \Sabre\VObject\Node::PROFILE_CALDAV; $backend = new \Sabre\CalDAV\Backend\PDO($pdo); } if($_REQUEST['a_upload']) { - $id[] = intval($_REQUEST['target']); + $id = intval($_REQUEST['target']); $ext = 'vcf'; $table = 'cards'; $column = 'addressbookid'; - $objects = new \Sabre\VObject\Splitter\VCard(@file_get_contents($src)); + $objects = new \Sabre\VObject\Splitter\VCard($carddata); $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; $backend = new \Sabre\CardDAV\Backend\PDO($pdo); + + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); } - - while ($object = $objects->getNext()) { - - if($_REQUEST['a_upload']) { - $object = $object->convert(\Sabre\VObject\Document::VCARD40); - } - - $ret = $object->validate($profile & \Sabre\VObject\Node::REPAIR); - - //level 3 Means that the document is invalid, - //level 2 means a warning. A warning means it's valid but it could cause interopability issues, - //level 1 means that there was a problem earlier, but the problem was automatically repaired. - - if($ret[0]['level'] < 3) { - do { - $duplicate = false; - $objectUri = random_string(40) . '.' . $ext; - - $r = q("SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", - dbesc($id[0]), - dbesc($objectUri) - ); - - if (count($r)) - $duplicate = true; - } while ($duplicate == true); - - if($_REQUEST['c_upload']) { - $backend->createCalendarObject($id, $objectUri, $object->serialize()); - } - - if($_REQUEST['a_upload']) { - $backend->createCard($id[0], $objectUri, $object->serialize()); - } - } - else { - if($_REQUEST['c_upload']) { - notice( '' . t('INVALID EVENT DISMISSED!') . '' . EOL . - '' . t('Summary: ') . '' . (($object->VEVENT->SUMMARY) ? $object->VEVENT->SUMMARY : t('Unknown')) . EOL . - '' . t('Date: ') . '' . (($object->VEVENT->DTSTART) ? $object->VEVENT->DTSTART : t('Unknown')) . EOL . - '' . t('Reason: ') . '' . $ret[0]['message'] . EOL - ); - } - - if($_REQUEST['a_upload']) { - notice( '' . t('INVALID CARD DISMISSED!') . '' . EOL . - '' . t('Name: ') . '' . (($object->FN) ? $object->FN : t('Unknown')) . EOL . - '' . t('Reason: ') . '' . $ret[0]['message'] . EOL - ); - } - } - } + + $ids = []; + import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, $ids, true); + + if(isset($cdavdata)) + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'import', + 'uri' => $cdavdata['uri'], + 'ids' => $ids, + 'card' => $carddata + ] + ]); } @unlink($src); } @@ -1408,7 +1313,19 @@ class Cdav extends Controller { if(! cdav_perms($id,$addressbooks)) return; + // get metadata before we delete it + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + $carddavBackend->deleteAddressBook($id); + + if($cdavdata) + build_sync_packet($channel['channel_id'], [ + 'addressbook' => [ + 'action' => 'drop', + 'uri' => $cdavdata['uri'] + ] + ]); + killme(); } @@ -1460,4 +1377,36 @@ class Cdav extends Controller { } + function get_cdav_data($id, $table) { + + $r = q("SELECT * FROM $table WHERE id = %d LIMIT 1", + intval($id) + ); + + if(! $r) + return false; + + return $r[0]; + } + + function request_to_array($req) { + + $f = []; + + $f['org'] = $req['org']; + $f['title'] = $req['title']; + $f['tel'] = $req['tel']; + $f['tel_type'] = $req['tel_type']; + $f['email'] = $req['email']; + $f['email_type'] = $req['email_type']; + $f['impp'] = $req['impp']; + $f['impp_type'] = $req['impp_type']; + $f['url'] = $req['url']; + $f['url_type'] = $req['url_type']; + $f['adr'] = $req['adr']; + $f['adr_type'] = $req['adr_type']; + $f['note'] = $req['note']; + + return $f; + } } diff --git a/include/cdav.php b/include/cdav.php new file mode 100644 index 000000000..d72caa442 --- /dev/null +++ b/include/cdav.php @@ -0,0 +1,186 @@ +ORG = $f['org']; + else + if($edit) + unset($vcard->ORG); + + + if($f['title']) + $vcard->TITLE = $f['title']; + else + if($edit) + unset($vcard->TITLE); + + if($edit) + unset($vcard->TEL); + if($f['tel']) { + $i = 0; + foreach($f['tel'] as $item) { + if($item) { + $vcard->add('TEL', $item, ['type' => $f['tel_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->EMAIL); + if($f['email']) { + $i = 0; + foreach($f['email'] as $item) { + if($item) { + $vcard->add('EMAIL', $item, ['type' => $f['email_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->IMPP); + if($f['impp']) { + $i = 0; + foreach($f['impp'] as $item) { + if($item) { + $vcard->add('IMPP', $item, ['type' => $f['impp_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->URL); + if($f['url']) { + $i = 0; + foreach($f['url'] as $item) { + if($item) { + $vcard->add('URL', $item, ['type' => $f['url_type'][$i]]); + } + $i++; + } + } + + if($edit) + unset($vcard->ADR); + if($f['adr']) { + $i = 0; + foreach($f['adr'] as $item) { + if($item) { + $vcard->add('ADR', $item, ['type' => $f['adr_type'][$i]]); + } + $i++; + } + } + + if($f['note']) { + $vcard->NOTE = $f['note']; + } + else + if($edit) + unset($vcard->NOTE); +} + + +/** + * @brief Import CardDAV or CalDAV card + * + * @param int $id card id + * @param str $ext card extension + * @param str $table name + * @param str $column name + * @param obj $objects + * @param str $profile + * @param obj $backend + * @param array $ids + * @param bool $notice + * + */ + +function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, &$ids, $notice = false) { + + $i = 0; + $newid = (count($ids) ? false : true); + + while ($object = $objects->getNext()) { + + if($_REQUEST['a_upload']) + $object = $object->convert(\Sabre\VObject\Document::VCARD40); + + $ret = $object->validate($profile & \Sabre\VObject\Node::REPAIR); + + //level 3 Means that the document is invalid, + //level 2 means a warning. A warning means it's valid but it could cause interopability issues, + //level 1 means that there was a problem earlier, but the problem was automatically repaired. + + if($ret[0]['level'] < 3) { + + if($newid) { + do { + $duplicate = false; + $objectUri = random_string(40) . '.' . $ext; + + $r = q("SELECT uri FROM $table WHERE $column = %d AND uri = '%s' LIMIT 1", + dbesc($id), + dbesc($objectUri) + ); + if (count($r)) + $duplicate = true; + } while ($duplicate == true); + $ids[$i] = $objectUri; + } + else + $objectUri = $ids[$i]; + + $i++; + + if($ext == 'ics') + $backend->createCalendarObject($id, $objectUri, $object->serialize()); + + if($ext == 'vcf') + $backend->createCard($id, $objectUri, $object->serialize()); + } + else { + if($notice && $ext == 'ics') { + notice( + '' . t('INVALID EVENT DISMISSED!') . '' . EOL . + '' . t('Summary: ') . '' . (($object->VEVENT->SUMMARY) ? $object->VEVENT->SUMMARY : t('Unknown')) . EOL . + '' . t('Date: ') . '' . (($object->VEVENT->DTSTART) ? $object->VEVENT->DTSTART : t('Unknown')) . EOL . + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL + ); + } + + if($notice && $exp == 'vcf') { + notice( + '' . t('INVALID CARD DISMISSED!') . '' . EOL . + '' . t('Name: ') . '' . (($object->FN) ? $object->FN : t('Unknown')) . EOL . + '' . t('Reason: ') . '' . $ret[0]['message'] . EOL + ); + } + } + } +} + + +function get_cdav_id($principaluri, $uri, $table) { + + $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + dbesc($principaluri), + dbesc($uri) + ); + if(! $r) + return false; + + return $r[0]['id']; +} diff --git a/include/import.php b/include/import.php index 6a3895b9f..0519052d8 100644 --- a/include/import.php +++ b/include/import.php @@ -1503,6 +1503,73 @@ function sync_files($channel, $files) { } } +/** + * @brief Synchronize addressbooks. + * + * @param array $channel + * @param array $data + */ +function sync_addressbook($channel, $data) { + + if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'CardDAV')) + return; + + logger("debug: " . print_r($data,true), LOGGER_DEBUG); + + require_once('include/cdav.php'); + + $principalUri = 'principals/' . $channel['channel_address']; + + if($data['action'] !== 'create') { + $id = get_cdav_id($principalUri, $data['uri'], 'addressbooks'); + if(! $id) + return; + } + + $pdo = \DBA::$dba->db; + + $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); + $addressbooks = $carddavBackend->getAddressBooksForUser($principalUri); + + switch($data['action']) { + + case 'create': + $carddavBackend->createAddressBook($principalUri, $data['uri'], $data['properties']); + break; + + case 'drop': + $carddavBackend->deleteAddressBook($id); + break; + + case 'edit': + $patch = new \Sabre\DAV\PropPatch($data['mutations']); + $carddavBackend->updateAddressBook($id, $patch); + $patch->commit(); + break; + + case 'delete_card': + $carddavBackend->deleteCard($id, $data['carduri']); + break; + + case 'update_card': + $vcard = \Sabre\VObject\Reader::read($data['card']); + $object = $vcard->convert(\Sabre\VObject\Document::VCARD40); + $cardData = $vcard->serialize(); + $carddavBackend->updateCard($id, $data['carduri'], $cardData); + break; + + case 'import': + $objects = new \Sabre\VObject\Splitter\VCard($data['card']); + $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; + import_cdav_card($id, 'vcf', 'cards', 'addressbookid', $objects, $profile, $carddavBackend, $data['ids']); + break; + + default: + break; + } +} + + /** * @brief Rename a key in an array. * diff --git a/include/zot.php b/include/zot.php index d08146287..c02dab162 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3611,6 +3611,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('app',$arr) && $arr['app']) sync_apps($channel,$arr['app']); + if(array_key_exists('addressbook',$arr) && $arr['addressbook']) + sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); -- cgit v1.2.3 From 60311eb04bc0fa564b9fbe179eb907989ff09d8f Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 20 Feb 2020 21:25:41 +0000 Subject: fix warning --- Zotlabs/Lib/Activity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 1ac3135db..5cb111381 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -1654,7 +1654,7 @@ class Activity { $answer_found = true; if (is_array($o['anyOf'][$c]['replies'])) { foreach($o['anyOf'][$c]['replies'] as $reply) { - if(array_key_exists('id',$reply) && $reply['id'] === $mid) { + if(is_array($reply) && array_key_exists('id',$reply) && $reply['id'] === $mid) { $found = true; } } @@ -1673,7 +1673,7 @@ class Activity { $answer_found = true; if (is_array($o['oneOf'][$c]['replies'])) { foreach($o['oneOf'][$c]['replies'] as $reply) { - if(array_key_exists('id',$reply) && $reply['id'] === $mid) { + if(is_array($reply) && array_key_exists('id',$reply) && $reply['id'] === $mid) { $found = true; } } -- cgit v1.2.3 From 9d97cc2a1d28cd201912870a5342e7eaf9285491 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 21 Feb 2020 10:44:26 +0000 Subject: implement optional events and polls filter --- Zotlabs/Module/Network.php | 24 +++++++++++++++++++----- Zotlabs/Widget/Activity_filter.php | 28 ++++++++++++++++++++++++++++ include/features.php | 16 ++++++++++++++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index a8efd0d9e..adfdc011b 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -340,7 +340,7 @@ class Network extends \Zotlabs\Web\Controller { // The special div is needed for liveUpdate to kick in for this page. // We only launch liveUpdate if you aren't filtering in some incompatible // way and also you aren't writing a comment (discovered in javascript). - + $maxheight = get_pconfig(local_channel(),'system','network_divmore_height'); if(! $maxheight) $maxheight = 400; @@ -411,10 +411,24 @@ class Network extends \Zotlabs\Web\Controller { } } - if($verb) { - $sql_extra .= sprintf(" AND item.verb like '%s' ", - dbesc(protect_sprintf('%' . $verb . '%')) - ); + if ($verb) { + + // the presence of a leading dot in the verb determines + // whether to match the type of activity or the child object. + // The name 'verb' is a holdover from the earlier XML + // ActivityStreams specification. + + if (substr($verb,0,1) === '.') { + $verb = substr($verb,1); + $sql_extra .= sprintf(" AND item.obj_type like '%s' ", + dbesc(protect_sprintf('%' . $verb . '%')) + ); + } + else { + $sql_extra .= sprintf(" AND item.verb like '%s' ", + dbesc(protect_sprintf('%' . $verb . '%')) + ); + } } if(strlen($file)) { diff --git a/Zotlabs/Widget/Activity_filter.php b/Zotlabs/Widget/Activity_filter.php index 0fc60ca9b..002a642cb 100644 --- a/Zotlabs/Widget/Activity_filter.php +++ b/Zotlabs/Widget/Activity_filter.php @@ -22,6 +22,13 @@ class Activity_filter { $filter_active = 'dm'; } + if(x($_GET,'verb')) { + $events_active = (($_GET['verb'] == '.Event') ? 'active' : ''); + $polls_active = (($_GET['verb'] == '.Question') ? 'active' : ''); + $filter_active = (($events_active) ? 'events' : 'polls'); + } + + $tabs[] = [ 'label' => t('Direct Messages'), 'icon' => 'envelope-o', @@ -30,6 +37,27 @@ class Activity_filter { 'title' => t('Show direct (private) messages') ]; + if(feature_enabled(local_channel(),'events_tab')) { + $tabs[] = [ + 'label' => t('Events'), + 'icon' => 'calendar', + 'url' => z_root() . '/' . $cmd . '/?verb=%2EEvent', + 'sel' => $events_active, + 'title' => t('Show posts that include events') + ]; + } + + if(feature_enabled(local_channel(),'polls_tab')) { + $tabs[] = [ + 'label' => t('Polls'), + 'icon' => 'bar-chart', + 'url' => z_root() . '/' . $cmd . '/?verb=%2EQuestion', + 'sel' => $polls_active, + 'title' => t('Show posts that include polls') + ]; + } + + if(Apps::system_app_installed(local_channel(), 'Privacy Groups')) { $groups = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", intval(local_channel()) diff --git a/include/features.php b/include/features.php index 87df0c50d..c6cfcf822 100644 --- a/include/features.php +++ b/include/features.php @@ -298,6 +298,22 @@ function get_features($filtered = true, $level = (-1)) { t('Network'), + [ + 'events_tab', + t('Events Filter'), + t('Ability to display only events'), + false, + get_config('feature_lock','events_tab') + ], + + [ + 'polls_tab', + t('Polls Filter'), + t('Ability to display only polls'), + false, + get_config('feature_lock','polls_tab') + ], + [ 'savedsearch', t('Saved Searches'), -- cgit v1.2.3 From ed28ef185e1e64b1666533d21df5de71741e5571 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 23 Feb 2020 08:45:39 +0000 Subject: polls can also appear in shares --- include/text.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/text.php b/include/text.php index 3dd0755a3..1475ff334 100644 --- a/include/text.php +++ b/include/text.php @@ -1731,7 +1731,7 @@ function prepare_body(&$item,$attach = false,$opts = false) { } } - $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE ])) ? format_poll($item, $s, $opts) : false); + $poll = (($item['obj_type'] === 'Question' && in_array($item['verb'],[ ACTIVITY_POST, ACTIVITY_UPDATE, ACTIVITY_SHARE ])) ? format_poll($item, $s, $opts) : false); if ($poll) { $s = $poll; } -- cgit v1.2.3 From 1297c8d2ae248f9cbd0403cf2f361476e1f909cd Mon Sep 17 00:00:00 2001 From: "M. Dent" Date: Sun, 23 Feb 2020 14:40:18 +0100 Subject: Fix: hang on too few items --- view/js/main.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/view/js/main.js b/view/js/main.js index e735e9d6b..94fd940b2 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -581,8 +581,10 @@ function contextualHelpFocus(target, openSidePanel) { function updatePageItems(mode, data) { if(mode === 'append') { + newitemcount = 0; $(data).each(function() { $('#page-end').before($(this)); + newitemcount++; }); if(loadingPage) { @@ -593,6 +595,10 @@ function updatePageItems(mode, data) { var e = document.getElementById('content-complete'); if(e) { pageHasMoreContent = false; + } else { + if (newitemcount < 1) { + pageUpdate(); + } } collapseHeight(); -- cgit v1.2.3 From 989fbe70cd566da4c5757527aa77022036af6274 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 24 Feb 2020 10:02:09 +0100 Subject: Implement DAV calendars sync with clones --- Zotlabs/Lib/Libsync.php | 5 +- Zotlabs/Module/Cdav.php | 156 ++++++++++++++++++++++++++++++++++++++---------- include/cdav.php | 4 +- include/import.php | 71 ++++++++++++++++++++++ include/zot.php | 3 + 5 files changed, 203 insertions(+), 36 deletions(-) diff --git a/Zotlabs/Lib/Libsync.php b/Zotlabs/Lib/Libsync.php index d1756cf47..c39720735 100644 --- a/Zotlabs/Lib/Libsync.php +++ b/Zotlabs/Lib/Libsync.php @@ -246,7 +246,10 @@ class Libsync { sync_apps($channel,$arr['app']); if(array_key_exists('addressbook',$arr) && $arr['addressbook']) - sync_addressbook($channel,$arr['addressbook']); + sync_addressbook($channel,$arr['addressbook']); + + if(array_key_exists('calendar',$arr) && $arr['calendar']) + sync_calendar($channel,$arr['calendar']); if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); diff --git a/Zotlabs/Module/Cdav.php b/Zotlabs/Module/Cdav.php index 593a78a53..ac73b8a5b 100644 --- a/Zotlabs/Module/Cdav.php +++ b/Zotlabs/Module/Cdav.php @@ -169,24 +169,34 @@ class Cdav extends Controller { logger("debug: method: " . $httpmethod, LOGGER_DEBUG); logger("debug: uri: " . $httpuri, LOGGER_DEBUG); - // currently we process CardDAV requests only if(strpos($httpuri, 'cdav/addressbooks')) { + $sync = 'addressbook'; + $cdavtable = 'addressbooks'; + } + elseif(strpos($httpuri, 'cdav/calendars')) { + $sync = 'calendar'; + $cdavtable = 'calendarinstances'; + } + else + $sync = false; + + if($sync) { $uri = basename($httpuri); $httpbody = file_get_contents('php://input'); logger("debug: body: " . $httpbody, LOGGER_DEBUG); - if($id = get_cdav_id($principalUri, explode("/", $httpuri)[4], 'addressbooks')) { + if($x = get_cdav_id($principalUri, explode("/", $httpuri)[4], $cdavtable)) { - $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + $cdavdata = $this->get_cdav_data($x['id'], $cdavtable); $etag = (isset($_SERVER['HTTP_IF_MATCH']) ? $_SERVER['HTTP_IF_MATCH'] : false); // delete if($httpmethod === 'DELETE' && $cdavdata['etag'] == $etag) build_sync_packet($channel['channel_id'], [ - 'addressbook' => [ + $sync => [ 'action' => 'delete_card', 'uri' => $cdavdata['uri'], 'carduri' => $uri @@ -197,7 +207,7 @@ class Cdav extends Controller { // update if($cdavdata['etag'] !== $etag) build_sync_packet($channel['channel_id'], [ - 'addressbook' => [ + $sync => [ 'action' => 'update_card', 'uri' => $cdavdata['uri'], 'carduri' => $uri, @@ -208,7 +218,7 @@ class Cdav extends Controller { else { // new build_sync_packet($channel['channel_id'], [ - 'addressbook' => [ + $sync => [ 'action' => 'import', 'uri' => $cdavdata['uri'], 'ids' => [ $uri ], @@ -326,6 +336,14 @@ class Cdav extends Controller { // set new calendar to be visible set_pconfig(local_channel(), 'cdav_calendar' , $id[0], 1); + + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'create', + 'uri' => $calendarUri, + 'properties' => $properties + ] + ]); } //create new calendar object via ajax request @@ -336,6 +354,8 @@ class Cdav extends Controller { if(!cdav_perms($id[0],$calendars,true)) return; + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); $tz = (($timezone) ? $timezone : date_default_timezone_get()); @@ -391,9 +411,17 @@ class Cdav extends Controller { $vcalendar->VEVENT->DTSTART['TZID'] = $tz; $calendarData = $vcalendar->serialize(); - $caldavBackend->createCalendarObject($id, $objectUri, $calendarData); + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'import', + 'uri' => $cdavdata['uri'], + 'ids' => [ $objectUri ], + 'card' => $calendarData + ] + ]); + killme(); } @@ -405,17 +433,24 @@ class Cdav extends Controller { if(! cdav_perms($id[0],$calendars)) return; + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $mutations = [ '{DAV:}displayname' => $_REQUEST['{DAV:}displayname'], '{http://apple.com/ns/ical/}calendar-color' => $_REQUEST['color'] ]; $patch = new \Sabre\DAV\PropPatch($mutations); - $caldavBackend->updateCalendar($id, $patch); - $patch->commit(); + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'edit', + 'uri' => $cdavdata['uri'], + 'mutations' => $mutations, + ] + ]); } //edit calendar object via ajax request @@ -423,9 +458,11 @@ class Cdav extends Controller { $id = explode(':', $_REQUEST['target']); - if(!cdav_perms($id[0],$calendars,true)) + if(! cdav_perms($id[0],$calendars,true)) return; + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); $tz = (($timezone) ? $timezone : date_default_timezone_get()); @@ -471,9 +508,17 @@ class Cdav extends Controller { $vcalendar->VEVENT->LOCATION = $location; $calendarData = $vcalendar->serialize(); - $caldavBackend->updateCalendarObject($id, $uri, $calendarData); + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'update_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri, + 'card' => $calendarData + ] + ]); + killme(); } @@ -482,13 +527,23 @@ class Cdav extends Controller { $id = explode(':', $_REQUEST['target']); - if(!cdav_perms($id[0],$calendars,true)) + if(! cdav_perms($id[0],$calendars,true)) return; + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $uri = $_REQUEST['uri']; $caldavBackend->deleteCalendarObject($id, $uri); + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'delete_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri + ] + ]); + killme(); } @@ -497,9 +552,11 @@ class Cdav extends Controller { $id = [$_REQUEST['id'][0], $_REQUEST['id'][1]]; - if(!cdav_perms($id[0],$calendars,true)) + if(! cdav_perms($id[0],$calendars,true)) return; + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $timezone = ((x($_POST,'timezone_select')) ? escape_tags(trim($_POST['timezone_select'])) : ''); $tz = (($timezone) ? $timezone : date_default_timezone_get()); @@ -535,9 +592,17 @@ class Cdav extends Controller { unset($vcalendar->VEVENT->DTEND); $calendarData = $vcalendar->serialize(); - $caldavBackend->updateCalendarObject($id, $uri, $calendarData); + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'update_card', + 'uri' => $cdavdata['uri'], + 'carduri' => $uri, + 'card' => $calendarData + ] + ]); + killme(); } @@ -602,11 +667,11 @@ class Cdav extends Controller { $id = $_REQUEST['id']; - $cdavdata = $this->get_cdav_data($id, 'addressbooks'); - if(! cdav_perms($id,$addressbooks)) return; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + $mutations = [ '{DAV:}displayname' => $_REQUEST['{DAV:}displayname'] ]; @@ -626,6 +691,7 @@ class Cdav extends Controller { //create addressbook card if($_REQUEST['create'] && $_REQUEST['target'] && $_REQUEST['fn']) { + $id = $_REQUEST['target']; $cdavdata = $this->get_cdav_data($id, 'addressbooks'); @@ -656,7 +722,6 @@ class Cdav extends Controller { process_cdav_card($fields, $vcard); $cardData = $vcard->serialize(); - $carddavBackend->createCard($id, $uri, $cardData); build_sync_packet($channel['channel_id'], [ @@ -674,11 +739,11 @@ class Cdav extends Controller { $id = $_REQUEST['target']; - $cdavdata = $this->get_cdav_data($id, 'addressbooks'); - - if(!cdav_perms($id,$addressbooks)) + if(! cdav_perms($id,$addressbooks)) return; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + $uri = $_REQUEST['uri']; $object = $carddavBackend->getCard($id, $uri); @@ -714,11 +779,11 @@ class Cdav extends Controller { $id = $_REQUEST['target']; - $cdavdata = $this->get_cdav_data($id, 'addressbooks'); - - if(!cdav_perms($id,$addressbooks)) + if(! cdav_perms($id,$addressbooks)) return; + $cdavdata = $this->get_cdav_data($id, 'addressbooks'); + $uri = $_REQUEST['uri']; $carddavBackend->deleteCard($id, $uri); @@ -758,9 +823,12 @@ class Cdav extends Controller { $ext = 'ics'; $table = 'calendarobjects'; $column = 'calendarid'; + $sync = 'calendar'; $objects = new \Sabre\VObject\Splitter\ICalendar($carddata); $profile = \Sabre\VObject\Node::PROFILE_CALDAV; $backend = new \Sabre\CalDAV\Backend\PDO($pdo); + + $cdavdata = $this->get_cdav_data($id, 'calendarinstances'); } if($_REQUEST['a_upload']) { @@ -768,6 +836,7 @@ class Cdav extends Controller { $ext = 'vcf'; $table = 'cards'; $column = 'addressbookid'; + $sync = 'addressbook'; $objects = new \Sabre\VObject\Splitter\VCard($carddata); $profile = \Sabre\VObject\Node::PROFILE_CARDDAV; $backend = new \Sabre\CardDAV\Backend\PDO($pdo); @@ -778,15 +847,14 @@ class Cdav extends Controller { $ids = []; import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, $ids, true); - if(isset($cdavdata)) - build_sync_packet($channel['channel_id'], [ - 'addressbook' => [ - 'action' => 'import', - 'uri' => $cdavdata['uri'], - 'ids' => $ids, - 'card' => $carddata - ] - ]); + build_sync_packet($channel['channel_id'], [ + $sync => [ + 'action' => 'import', + 'uri' => $cdavdata['uri'], + 'ids' => $ids, + 'card' => $carddata + ] + ]); } @unlink($src); } @@ -1095,7 +1163,18 @@ class Cdav extends Controller { if(! cdav_perms($id,$calendars)) killme(); - set_pconfig(local_channel(), 'cdav_calendar' , argv(3), argv(4)); + $cdavdata = $this->get_cdav_data($id, 'calendarinstances'); + + set_pconfig(local_channel(), 'cdav_calendar', $id, argv(4)); + + build_sync_packet(local_channel(), [ + 'calendar' => [ + 'action' => 'switch', + 'uri' => $cdavdata['uri'], + 'switch' => intval(argv(4)) + ] + ]); + killme(); } @@ -1106,7 +1185,18 @@ class Cdav extends Controller { if(! cdav_perms($id[0],$calendars)) killme(); + // get metadata before we delete it + $cdavdata = $this->get_cdav_data($id[0], 'calendarinstances'); + $caldavBackend->deleteCalendar($id); + + build_sync_packet($channel['channel_id'], [ + 'calendar' => [ + 'action' => 'drop', + 'uri' => $cdavdata['uri'] + ] + ]); + killme(); } diff --git a/include/cdav.php b/include/cdav.php index d72caa442..cdf7775db 100644 --- a/include/cdav.php +++ b/include/cdav.php @@ -175,12 +175,12 @@ function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backe function get_cdav_id($principaluri, $uri, $table) { - $r = q("SELECT id FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", + $r = q("SELECT * FROM $table WHERE principaluri = '%s' AND uri = '%s' LIMIT 1", dbesc($principaluri), dbesc($uri) ); if(! $r) return false; - return $r[0]['id']; + return $r[0]; } diff --git a/include/import.php b/include/import.php index 0519052d8..bfe71963f 100644 --- a/include/import.php +++ b/include/import.php @@ -1503,6 +1503,7 @@ function sync_files($channel, $files) { } } + /** * @brief Synchronize addressbooks. * @@ -1570,6 +1571,76 @@ function sync_addressbook($channel, $data) { } +/** + * @brief Synchronize calendars. + * + * @param array $channel + * @param array $data + */ +function sync_calendar($channel, $data) { + + if(! \Zotlabs\Lib\Apps::system_app_installed($channel['channel_id'], 'Calendar')) + return; + + logger("debug: " . print_r($data,true), LOGGER_DEBUG); + + require_once('include/cdav.php'); + + $principalUri = 'principals/' . $channel['channel_address']; + + if($data['action'] !== 'create') { + $x = get_cdav_id($principalUri, $data['uri'], 'calendarinstances'); + if(! $x) + return; + $id = [ $x['id'], $x['calendarid'] ]; + } + + $pdo = \DBA::$dba->db; + + $caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); + $calendars = $caldavBackend->getCalendarsForUser($principalUri); + + switch($data['action']) { + + case 'create': + $id = $caldavBackend->createCalendar($principalUri, $data['uri'], $data['properties']); + set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], 1); + break; + + case 'drop': + $caldavBackend->deleteCalendar($id); + break; + + case 'edit': + $patch = new \Sabre\DAV\PropPatch($data['mutations']); + $caldavBackend->updateCalendar($id, $patch); + $patch->commit(); + break; + + case 'delete_card': + $caldavBackend->deleteCalendarObject($id, $data['carduri']); + break; + + case 'update_card': + $caldavBackend->updateCalendarObject($id, $data['carduri'], $data['card']); + break; + + case 'switch': + set_pconfig($channel['channel_id'], 'cdav_calendar', $id[0], $data['switch']); + break; + + case 'import': + $objects = new \Sabre\VObject\Splitter\ICalendar($data['card']); + $profile = \Sabre\VObject\Node::PROFILE_CALDAV; + import_cdav_card($id, 'ics', 'calendarobjects', 'calendarid', $objects, $profile, $caldavBackend, $data['ids']); + break; + + default: + break; + } +} + + /** * @brief Rename a key in an array. * diff --git a/include/zot.php b/include/zot.php index c02dab162..5d5ac8424 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3614,6 +3614,9 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) { if(array_key_exists('addressbook',$arr) && $arr['addressbook']) sync_addressbook($channel,$arr['addressbook']); + if(array_key_exists('calendar',$arr) && $arr['calendar']) + sync_calendar($channel,$arr['calendar']); + if(array_key_exists('chatroom',$arr) && $arr['chatroom']) sync_chatrooms($channel,$arr['chatroom']); -- cgit v1.2.3 From 8bcdc24fcbb308f052d996291f5ef0b8f4b606f1 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 24 Feb 2020 11:38:23 +0100 Subject: Code reuse --- Zotlabs/Module/Well_known.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Zotlabs/Module/Well_known.php b/Zotlabs/Module/Well_known.php index 140ab260d..0d7b222b8 100644 --- a/Zotlabs/Module/Well_known.php +++ b/Zotlabs/Module/Well_known.php @@ -65,11 +65,6 @@ class Well_known extends \Zotlabs\Web\Controller { killme(); case 'caldav': - if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { - http_status('301', 'moved permanently'); - goaway(z_root() . '/cdav'); - }; - case 'carddav': if ($_SERVER['REQUEST_METHOD'] == 'PROPFIND') { http_status('301', 'moved permanently'); -- cgit v1.2.3 From c28ba4be37bdce7bd0c0f5fd729b6ff951f741fd Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Mon, 24 Feb 2020 11:39:26 +0100 Subject: Update cdav import parameters comment --- include/cdav.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cdav.php b/include/cdav.php index cdf7775db..ef248a9fe 100644 --- a/include/cdav.php +++ b/include/cdav.php @@ -3,7 +3,7 @@ /** * @brief Process CardDAV card * - * @param array $f fields array + * @param array $f fields * @param obj $vcard SabreDAV object * @param bool $edit update card * @@ -96,7 +96,7 @@ function process_cdav_card($f, &$vcard, $edit = false) { /** * @brief Import CardDAV or CalDAV card * - * @param int $id card id + * @param mixed $id card id * @param str $ext card extension * @param str $table name * @param str $column name -- cgit v1.2.3 From 3d6fa049da953b2cd73206bbae673f599e9a50eb Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Tue, 25 Feb 2020 21:37:49 +0100 Subject: Update hstrings.php --- view/ru/hstrings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php index 122cb48a5..5a7323ea8 100644 --- a/view/ru/hstrings.php +++ b/view/ru/hstrings.php @@ -2772,8 +2772,8 @@ App::$strings["My Chatrooms"] = "Мои чаты"; App::$strings["Channel Export"] = "Экспорт канала"; App::$strings["Purchase"] = "Купить"; App::$strings["Undelete"] = "Восстановить"; -App::$strings["Add to app-tray"] = "Добавить в app-tray"; -App::$strings["Remove from app-tray"] = "Удалить из app-tray"; +App::$strings["Add to app-tray"] = "Добавить в правое меню"; +App::$strings["Remove from app-tray"] = "Удалить из правого меню"; App::$strings["Pin to navbar"] = "Добавить на панель навигации"; App::$strings["Unpin from navbar"] = "Удалить с панели навигации"; App::$strings["Privacy conflict. Discretion advised."] = "Конфиликт настроек конфиденциальности."; -- cgit v1.2.3 From 47d80df81c42105b1f0deeb9fef71fecddc574f5 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Tue, 25 Feb 2020 21:38:33 +0100 Subject: Update hmessages.po --- view/ru/hmessages.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po index d8ddafa96..e951ee2a3 100644 --- a/view/ru/hmessages.po +++ b/view/ru/hmessages.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: hubzilla\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-01-19 11:37+0200\n" -"PO-Revision-Date: 2020-01-19 11:43+0200\n" +"PO-Revision-Date: 2020-02-25 23:38+0200\n" "Last-Translator: Max Kostikov \n" "Language-Team: Russian (http://www.transifex.com/Friendica/hubzilla/language/ru/)\n" "MIME-Version: 1.0\n" @@ -12268,11 +12268,11 @@ msgstr "Восстановить" #: ../../Zotlabs/Lib/Apps.php:567 msgid "Add to app-tray" -msgstr "Добавить в app-tray" +msgstr "Добавить в правое меню" #: ../../Zotlabs/Lib/Apps.php:568 msgid "Remove from app-tray" -msgstr "Удалить из app-tray" +msgstr "Удалить из правого меню" #: ../../Zotlabs/Lib/Apps.php:569 msgid "Pin to navbar" -- cgit v1.2.3 From 93ad3eb6f1456ad2117b1e757f48edace3d2758f Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 26 Feb 2020 00:12:23 +0100 Subject: Update hmessages.po --- view/ru/hmessages.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po index e951ee2a3..764228ad2 100644 --- a/view/ru/hmessages.po +++ b/view/ru/hmessages.po @@ -9583,11 +9583,11 @@ msgstr "Результаты поиска для: %s" #: ../../Zotlabs/Module/Notes.php:56 msgid "Notes App" -msgstr "Приложение \"Заметки\"" +msgstr "Приложение \"Записки\"" #: ../../Zotlabs/Module/Notes.php:57 msgid "A simple notes app with a widget (note: notes are not encrypted)" -msgstr "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)" +msgstr "Простое приложение для записок с виджетом (примечание: записки не зашифрованы)" #: ../../Zotlabs/Module/Moderate.php:65 msgid "Comment approved" @@ -11015,7 +11015,7 @@ msgstr "Форумы" #: ../../Zotlabs/Widget/Notes.php:21 ../../Zotlabs/Lib/Apps.php:368 #: ../../extend/addon/hzaddons/workflow/workflow.php:2592 msgid "Notes" -msgstr "Заметки" +msgstr "Записки" #: ../../Zotlabs/Widget/Suggestions.php:53 msgid "Suggestions" -- cgit v1.2.3 From 082826ee444cb1a24306a128c64cb2e7de631291 Mon Sep 17 00:00:00 2001 From: Max Kostikov Date: Wed, 26 Feb 2020 00:12:57 +0100 Subject: Update hstrings.php --- view/ru/hstrings.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php index 5a7323ea8..62585df9b 100644 --- a/view/ru/hstrings.php +++ b/view/ru/hstrings.php @@ -2146,8 +2146,8 @@ App::$strings["Welcome to Hubzilla!"] = "Добро пожаловать в Hubz App::$strings["You have got no unseen posts..."] = "У вас нет непросмотренных публикаций..."; App::$strings["Items tagged with: %s"] = "Объекты помечены как: %s"; App::$strings["Search results for: %s"] = "Результаты поиска для: %s"; -App::$strings["Notes App"] = "Приложение \"Заметки\""; -App::$strings["A simple notes app with a widget (note: notes are not encrypted)"] = "Простое приложение для заметок с виджетом (примечание: заметки не зашифрованы)"; +App::$strings["Notes App"] = "Приложение \"Записки\""; +App::$strings["A simple notes app with a widget (note: notes are not encrypted)"] = "Простое приложение для записок с виджетом (примечание: записки не зашифрованы)"; App::$strings["Comment approved"] = "Комментарий одобрен"; App::$strings["Comment deleted"] = "Комментарий удалён"; App::$strings["Webpages App"] = "Приложение \"Веб-страницы\""; @@ -2480,7 +2480,7 @@ App::$strings["View your connections and/or add somebody whose address you alrea App::$strings["View your personal stream (this may be empty until you add some connections)"] = "Ваш персональный поток (может быть пуст пока вы не добавите контакты)"; App::$strings["View the public stream. Warning: this content is not moderated"] = "Просмотр публичного потока. Предупреждение: этот контент не модерируется"; App::$strings["Forums"] = "Форумы"; -App::$strings["Notes"] = "Заметки"; +App::$strings["Notes"] = "Записки"; App::$strings["Suggestions"] = "Рекомендации"; App::$strings["See more..."] = "Просмотреть больше..."; App::$strings["New Network Activity"] = "Новая сетевая активность"; -- cgit v1.2.3 From e7f25b84664c158343621c391b8653042d5be53c Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 26 Feb 2020 09:51:40 +0000 Subject: implement poll UI in jot --- Zotlabs/Module/Item.php | 61 +++++++++++++++++++++++++++++++++++++-- include/conversation.php | 4 ++- view/css/conversation.css | 20 ++++++++----- view/theme/redbasic/css/style.css | 4 +++ view/tpl/jot-header.tpl | 19 ++++++++++++ view/tpl/jot.tpl | 40 +++++++++++++++++++++++-- 6 files changed, 133 insertions(+), 15 deletions(-) diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 4b866eace..86b5c1c7a 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -271,7 +271,9 @@ class Item extends Controller { $consensus = intval($_REQUEST['consensus']); $nocomment = intval($_REQUEST['nocomment']); - + + $is_poll = ((trim($_REQUEST['poll_answers'][0]) != '' && trim($_REQUEST['poll_answers'][1]) != '') ? true : false); + // 'origin' (if non-zero) indicates that this network is where the message originated, // for the purpose of relaying comments to other conversation members. // If using the API from a device (leaf node) you must set origin to 1 (default) or leave unset. @@ -920,7 +922,21 @@ class Item extends Controller { $mid = z_root() . '/item/' . $uuid; } - $obj = $this->extract_poll_data($body,[ 'item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny ]); + + if($is_poll) { + $poll = [ + 'question' => $body, + 'answers' => $_REQUEST['poll_answers'], + 'multiple_answers' => $_REQUEST['poll_multiple_answers'], + 'expire_value' => $_REQUEST['poll_expire_value'], + 'expire_unit' => $_REQUEST['poll_expire_unit'] + ]; + $obj = $this->extract_poll_data($poll, [ 'item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny ]); + } + else { + $obj = $this->extract_bb_poll_data($body,[ 'item_private' => $private, 'allow_cid' => $str_contact_allow, 'allow_gid' => $str_contact_deny ]); + } + if ($obj) { $obj['url'] = $mid; $obj['attributedTo'] = channel_url($channel); @@ -1397,7 +1413,7 @@ class Item extends Controller { return $ret; } - function extract_poll_data(&$body,$item) { + function extract_bb_poll_data(&$body,$item) { $multiple = false; @@ -1457,5 +1473,44 @@ class Item extends Controller { } + function extract_poll_data($poll, $item) { + + $multiple = intval($poll['multiple_answers']); + $expire_value = intval($poll['expire_value']); + $expire_unit = $poll['expire_unit']; + $question = $poll['question']; + $answers = $poll['answers']; + + $obj = []; + $ptr = []; + $obj['type'] = 'Question'; + $obj['content'] = bbcode($question); + + foreach($answers as $answer) { + if(trim($answer)) + $ptr[] = [ 'name' => escape_tags($answer), 'type' => 'Note', 'replies' => [ 'type' => 'Collection', 'totalItems' => 0 ]]; + } + + if($multiple) { + $obj['anyOf'] = $ptr; + } + else { + $obj['oneOf'] = $ptr; + } + + $obj['endTime'] = datetime_convert(date_default_timezone_get(), 'UTC', 'now + ' . $expire_value . ' ' . $expire_unit, ATOM_TIME); + + if ($item['item_private']) { + $obj['to'] = Activity::map_acl($item); + } + else { + $obj['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + } + + return $obj; + + } + + } diff --git a/include/conversation.php b/include/conversation.php index 0098a694d..ba0f61196 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -1293,7 +1293,7 @@ function hz_status_editor($a, $x, $popup = false) { $feature_voting = feature_enabled($x['profile_uid'], 'consensus_tools'); if(x($x, 'hide_voting')) $feature_voting = false; - + $feature_nocomment = feature_enabled($x['profile_uid'], 'disable_comments'); if(x($x, 'disable_comments')) $feature_nocomment = false; @@ -1441,6 +1441,8 @@ function hz_status_editor($a, $x, $popup = false) { '$embedPhotosModalOK' => t('OK'), '$setloc' => $setloc, '$voting' => t('Toggle voting'), + '$poll' => t('Toggle poll'), + '$multiple_answers' => ['poll_multiple_answers', t("Allow multiple answers")], '$feature_voting' => $feature_voting, '$consensus' => ((array_key_exists('item',$x)) ? $x['item']['item_consensus'] : 0), '$nocommenttitle' => t('Disable comments'), diff --git a/view/css/conversation.css b/view/css/conversation.css index f7804f5dd..287d662ae 100644 --- a/view/css/conversation.css +++ b/view/css/conversation.css @@ -1,15 +1,18 @@ /* jot */ +.jothidden { + display:none; +} -.jothidden input[type="text"] { - border: 0px; - margin: 0px; - height: 2.5rem; - width: 100%; +.jot-poll-option { + position: relative; } -.jothidden { - display:none; +.poll-option-close { + position: absolute; + right: 0; + top: 0; + padding: 0.25rem 0 0.25rem 0.5rem; } #jot-title-wrap, @@ -18,7 +21,8 @@ border-bottom: 1px solid rgba(0, 0, 0, .2); } -#jot-attachment-wrap { +#jot-attachment-wrap, +#jot-poll-wrap { border-top: 1px solid rgba(0, 0, 0, .2); } diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 3bee84378..1ababecfc 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -1605,6 +1605,10 @@ dl.bb-dl > dd > li { font-size: 100%; } +.bootstrap-tagsinput input { + height: 2.5rem; +} + /* Abusing theme-green is less work than makeing a new new one */ .theme-green .back-bar .selected-bar { background-color: #000000; diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl index 7b1f4ee05..d519fd666 100755 --- a/view/tpl/jot-header.tpl +++ b/view/tpl/jot-header.tpl @@ -58,6 +58,9 @@ var activeCommentText = ''; $('#id_mimetype').on('load', jotSetMime); $('#id_mimetype').on('change', jotSetMime); + $('#jot-add-option').on('click', jotAddOption); + $(document).on('click', '.poll-option-close', jotRemoveOption); + function jotSetMime() { var mtype = $('#id_mimetype').val(); if(mtype == 'text/bbcode') @@ -122,6 +125,7 @@ var activeCommentText = ''; activeCommentID = 0; }, }); + }); function deleteCheckedItems() { @@ -309,6 +313,7 @@ var activeCommentText = ''; function itemCancel() { $("#jot-title").val(''); $("#profile-jot-text").val(''); + $(".jot-poll-option input").val(''); $("#jot-category").tagsinput('removeAll'); postSaveChanges('clean'); @@ -317,6 +322,7 @@ var activeCommentText = ''; $(".jothidden").hide(); $("#profile-jot-text").removeClass('jot-expanded'); $("#profile-jot-tools").addClass('d-none'); + $("#jot-poll-wrap").addClass('d-none'); $("#jot-preview-content").html('').hide(); editor = false; {{else}} @@ -512,6 +518,19 @@ var activeCommentText = ''; } + function initPoll() { + $('#jot-poll-wrap').toggleClass('d-none'); + } + + function jotAddOption() { + var option = '
'; + $('#jot-poll-options').append(option); + } + + function jotRemoveOption(e) { + $(this).closest('.jot-poll-option').remove(); + } +