card-mod-bookmarks 0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []