card-mod-bookmarks 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1c6a2b131d1140a546ee8c12b5b947deba44b681666eccbb8c7c4f46c927ba39
4
+ data.tar.gz: fe66a0b037a7257d68f31bdeb828c675541ab12136e53926f8174c49f86c6979
5
+ SHA512:
6
+ metadata.gz: 549367ca28dba27ad03eccdd327cc7623403bb54a3992c527205cac4f45e89e27dd9a6236e8159d2d2bb27bb546a5cc91a99e429cc723cc2a86b4811049a3296
7
+ data.tar.gz: b4988234f764262a848cb8eee1fed09d346343ce9213575500784b8f01a7035e87eece0b03a2942e0107c28b1545bd5ec2732bb7c22837f7b14886b4092c3144
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ <!--
2
+ # @title README - mod: bookmarks
3
+ -->
4
+
5
+ # Bookmarks mod
6
+
7
+ This mod provides functionality for:
8
+
9
+ - bookmarking / unbookmarking cards with a single click
10
+ - db storage of those bookmarks for signed-in users
11
+ - session storage for non-signed in users
12
+ - saving session bookmarks in db when users create accounts
13
+ - navigating one's bookmarked content
14
+ - letting users "follow" cards they have bookmarked
15
+
16
+ ## Sets modified
17
+
18
+ ### Abstract::Bookmarkable
19
+
20
+ By including this set (via `include_set Abstract::Bookmarkable`), a set is made
21
+ bookmarkable. It has a `:toggle_bookmark` event that can be triggered using the
22
+ standard trigger API. Eg `card.update! trigger: :toggle_bookmark`.
23
+
24
+ It also provides a `#currently_bookmarked?` method, as well as the following
25
+ views:
26
+
27
+ - :bookmark - shows the toggleable bookmark icon and the number of bookmarkers
28
+ - :title_with_bookmark - prepends the bookmark view to a title.
29
+ - :box_top - uses :title_with_bookmark in boxes
30
+ - :bar_left - uses :title_with_bookmark in bars
31
+
32
+ ### Abstract::Bookmarker
33
+
34
+ A bookmarker is a user that bookmarks. Any set that includes this one will be
35
+ able to bookmark other sets.
36
+
37
+ ### Abstract::Accountable
38
+
39
+ Extended to include `Abstract::Bookmarker`. Because most user sets already
40
+ include `Abstract::Accountable`, monkeys will seldom need to
41
+ include `Abstract::Bookmarker` explicitly.
42
+
43
+ ### Right::Account (Cards that end in +*account)
44
+
45
+ Extended with `:save_session_bookmarks` event so that session bookmarks can be
46
+ saved when an account is created.
47
+
48
+ ### Right::Bookmarkers (Cards that end in +bookmarkers)
49
+
50
+ Searches that handle counting number of bookmarkers that have bookmarked a given
51
+ card.
52
+
53
+ ### Right::Bookmarks (Cards that end in +bookmarks)
54
+
55
+ These are the cards that actually store the bookmarks. For example, if `Joe
56
+ User` bookmarks the card named `Pineapple`, then `Joe User+bookmarks` will
57
+ be a list of cards that contains the item `Pineapple`
58
+
59
+ ### Self::Anonymous (the card "Anonymous")
60
+
61
+ When a user is not signed in, the "Anonymous" card acts as their user card.
62
+ This mod extends that card to allow for anonymous bookmarks to be stored in
63
+ the session.
64
+
65
+ ### Self::Bookmarked (the card "Bookmarked")
66
+
67
+ This card is created as a follow option, making it possible to follow cards
68
+ that you have bookmarked.
@@ -0,0 +1,66 @@
1
+ class Card
2
+ module Bookmark
3
+ class << self
4
+ CURRENT_IDS_KEY = "BM-current_ids".freeze
5
+ CURRENT_BOOKMARKS_KEY = "BM-current_bookmarks".freeze
6
+
7
+ def ok?
8
+ Auth.current.respond_to?(:bookmarks_card)
9
+ end
10
+
11
+ # @return Hash key is type_id, value is list of ids
12
+ def current_bookmarks
13
+ cache.fetch CURRENT_BOOKMARKS_KEY do
14
+ ok? ? bookmark_hash_for_list_card(current_list_card) : {}
15
+ end
16
+ end
17
+
18
+ # @param list_card [Card] +bookmarks card for (eg) user
19
+ # @return [Hash]. keys are type_ids, values are list of bookmarked card ids
20
+ def bookmark_hash_for_list_card list_card
21
+ list_card.item_cards.each_with_object({}) do |item, hash|
22
+ hash[item.type_id] ||= []
23
+ hash[item.type_id] << item.id
24
+ end
25
+ end
26
+
27
+ def current_list_card
28
+ Auth.current.bookmarks_card if ok?
29
+ end
30
+
31
+ def current_ids
32
+ cache.fetch CURRENT_IDS_KEY do # MOVE to session?
33
+ ok? ? current_list_card.item_ids : []
34
+ end
35
+ end
36
+
37
+ def bookmark_hash
38
+ ok? ? yield : {}
39
+ end
40
+
41
+ def id_restriction bookmarked=true
42
+ if current_ids.empty?
43
+ yield [] if bookmarked
44
+ else
45
+ yield([(bookmarked ? "in" : "not in")] + current_ids)
46
+ end
47
+ end
48
+
49
+ def cache
50
+ Card.cache.soft
51
+ end
52
+
53
+ def clear
54
+ cache.delete CURRENT_IDS_KEY
55
+ cache.delete CURRENT_BOOKMARKS_KEY
56
+ end
57
+
58
+ def add_sort_join rel, join_field
59
+ rel.joins(
60
+ "LEFT JOIN counts cts " \
61
+ "ON #{join_field} = cts.left_id AND cts.right_id = #{Card::BookmarkersID}"
62
+ )
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1 @@
1
+ card_accessor :bookmarks, type: PointerID
@@ -0,0 +1,3 @@
1
+ include_set Abstract::Bookmarker
2
+
3
+ card_accessor :bookmarks, type: PointerID
@@ -0,0 +1,42 @@
1
+ card_accessor :bookmarkers, type: :search_type
2
+
3
+ event :toggle_bookmark, :prepare_to_validate, on: :save, trigger: :required do
4
+ toggle_bookmarks_item
5
+ list = Card::Bookmark.current_list_card
6
+ if Auth.signed_in?
7
+ list.save!
8
+ else
9
+ # when using save!, session card was getting saved to db
10
+ list.store_in_session
11
+ abort :triumph
12
+ end
13
+ end
14
+
15
+ def currently_bookmarked?
16
+ Card::Bookmark.current_ids.include? id
17
+ end
18
+
19
+ format :html do
20
+ view :bookmark, wrap: :slot do
21
+ link_to_view :bookmark, field_nest(:bookmarkers, view: :toggle),
22
+ path: { action: :update, card: { trigger: :toggle_bookmark } }
23
+ end
24
+
25
+ view :title_with_bookmark, template: :haml
26
+
27
+ view :box_top do
28
+ render :title_with_bookmark
29
+ end
30
+
31
+ view :bar_left do
32
+ render :title_with_bookmark
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def toggle_bookmarks_item
39
+ action = currently_bookmarked? ? :drop : :add
40
+ Card::Bookmark.current_list_card.send "#{action}_item", name
41
+ Card::Bookmark.clear
42
+ end
@@ -0,0 +1,3 @@
1
+ .title-with-bookmark
2
+ = render :bookmark
3
+ = render :title_link
@@ -0,0 +1,6 @@
1
+ event :save_session_bookmarks, :integrate, on: :create do
2
+ session_bookmark_card = Card[:anonymous].bookmarks_card
3
+ return if session_bookmark_card.item_names.blank?
4
+
5
+ left.add_subfield :bookmarks, type: :pointer, content: session_bookmark_card.content
6
+ end
@@ -0,0 +1,5 @@
1
+ .bookmark-toggle._stop_propagation{ class: bookmark_status_class }
2
+ = fa_icon "bookmark"
3
+ %span.bookmark-count
4
+ = count
5
+ // = modal_link count, class: "bookmark-count"
@@ -0,0 +1,17 @@
1
+ # cache # of users who have bookmarked this metric/topic/whatever(=left)
2
+ include_set Abstract::ListRefCachedCount,
3
+ type_to_count: :user,
4
+ list_field: :bookmarks,
5
+ count_trait: :bookmarkers
6
+
7
+ def active?
8
+ left&.currently_bookmarked?
9
+ end
10
+
11
+ format :html do
12
+ view :toggle, cache: :never, template: :haml
13
+
14
+ def bookmark_status_class
15
+ card.active? ? "active-bookmark" : "inactive-bookmark"
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ include_set Type::List
2
+ include_set Abstract::IdPointer
3
+
4
+ def history?
5
+ false
6
+ end
7
+
8
+ def followable?
9
+ false
10
+ end
11
+
12
+ def item_cards_of_type type
13
+ type_id = type.card_id
14
+ item_cards.select { |i| i.type_id == type_id }
15
+ end
@@ -0,0 +1,7 @@
1
+ # card_accessor :bookmarks, type: SessionID
2
+ # accessor wasn't working, because
3
+ #
4
+
5
+ def bookmarks_card
6
+ @bookmarks_card ||= fetch(:bookmarks, new: { type_id: Card::SessionID })
7
+ end
@@ -0,0 +1,20 @@
1
+ include_set Abstract::FollowOption
2
+
3
+ restrictive_follow_opts position: 3
4
+
5
+ follower_candidate_ids do |card|
6
+ Card.search({ right_plus: [:bookmarks, { refer_to: card.name }], return: :id },
7
+ "bookmarked follower candidate ids for #{card.name}")
8
+ end
9
+
10
+ def title
11
+ 'Following content you bookmarked'
12
+ end
13
+
14
+ def label
15
+ 'follow if I bookmarked'
16
+ end
17
+
18
+ def description set_card
19
+ "#{set_card.follow_label} I bookmarked"
20
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: card-mod-bookmarks
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Philipp Kühl
8
+ - Ethan McCutchen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2021-10-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: card
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: card-mod-counts
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description: WikiRate.org is driving development on this to-be-generalized decko bookmarking
43
+ tool.
44
+ email:
45
+ - info@decko.org
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - README.md
51
+ - lib/card/bookmark.rb
52
+ - set/abstract/01_bookmarker.rb
53
+ - set/abstract/accountable.rb
54
+ - set/abstract/bookmarkable.rb
55
+ - set/abstract/title_with_bookmark.haml
56
+ - set/right/account.rb
57
+ - set/right/bookmarkers.rb
58
+ - set/right/bookmarkers/toggle.haml
59
+ - set/right/bookmarks.rb
60
+ - set/self/anonymous.rb
61
+ - set/self/bookmarked.rb
62
+ homepage: http://decko.org
63
+ licenses:
64
+ - GPL-3.0
65
+ metadata:
66
+ card-mod: bookmarks
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '2.5'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.2.28
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: bookmarking on decko cards
86
+ test_files: []