-
-
Save sergii/e837202a628ca3e608f9731aa45c64b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/filters/base_filter.rb | |
class BaseFilter | |
include ActiveModel::Model | |
include ActiveModel::Attributes | |
def initialize(session) | |
@_session = session | |
super(@_session.fetch(:filters, {})[filter_resource_class]) | |
end | |
def apply!(_chain) | |
raise NotImplementedError | |
end | |
def active_for?(attribute, value=true) | |
filter_attribute = send(attribute) | |
return filter_attribute.include?(value) if filter_attribute.is_a?(Enumerable) | |
filter_attribute == value | |
end | |
def filter_resource_class | |
@filter_resource_class || self.class.name.match(/\A(?<resource>.*)Filter\Z/)[:resource] | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/filters/base_filter.rb | |
class BaseFilter | |
# ... | |
def merge!(_attribute, _value) | |
@_session[:filters] ||= {} | |
@_session[:filters][filter_resource_class] ||= {} | |
end | |
end | |
# app/filters/embed_filter.rb | |
class EmbedFilter < BaseFilter | |
# ... | |
def merge!(attribute, value) | |
super | |
if send(attribute).is_a? Array | |
if send(attribute).include? value | |
send(attribute).delete value | |
else | |
send(attribute) << value | |
end | |
end | |
@_session[:filters]["Embed"].merge!(attribute => send(attribute)) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/filters/board_filter.rb | |
class BoardFilter < BaseFilter | |
attribute :query, :string, default: "" | |
def apply!(chain) | |
chain = chain.search(query) if query.present? | |
chain | |
end | |
def merge!(attribute, value) | |
super | |
send(:"#{attribute}=", value) | |
@_session[:filters]["Board"].merge!(attribute => send(attribute)) | |
end | |
end | |
# app/filters/history_entry_filter.rb | |
class HistoryEntryFilter < BaseFilter | |
attribute :show_all, :boolean, default: false | |
def apply!(chain) | |
chain = chain.with_reactions unless show_all | |
chain | |
end | |
def merge!(attribute, value) | |
super | |
send(:"#{attribute}=", !send(attribute)) | |
@_session[:filters]["HistoryEntry"].merge!(attribute => send(attribute)) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/boards_controller.rb | |
class BoardsController | |
# ... | |
def show | |
@embed = @board.embeds.build | |
@embed_import = EmbedImport.new(board: @board) | |
@embeds = filter_for("Embed").apply!(@board.embeds) | |
end | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/boards_controller.rb | |
class BoardsController < ApplicationController | |
include Filterable | |
def index | |
set_filter_for!("Board", "query", "") | |
@boards = current_user.boards.order(:created_at) | |
@boards = @boards.search(filter_for("Board", "query")) if filter_for("Board", "query").present? | |
end | |
def show | |
set_filter_for!("Embed", "embeddable_type", %w[MediaAsset OEmbedLink]) | |
@embed = @board.embeds.build | |
@embed_import = EmbedImport.new(board: @board) | |
@embeds = @board.embeds.where(session[:filters]["Embed"]) | |
end | |
# ... | |
end | |
# app/controllers/embed_controller.rb | |
class EmbedsController < ApplicationController | |
include Filterable | |
# ... | |
def show | |
set_filter_for!("HistoryEntry", "show_all", false) | |
@comment ||= Comment.new(user: current_user) | |
@comment.build_history_entry(embed: @embed) | |
@history_entries = @embed.history_entries.includes(:entryable) | |
@history_entries = @history_entries.with_reactions unless filter_for("HistoryEntry", "show_all") | |
end | |
# ... | |
end | |
# app/reflexes/filter_reflex.rb | |
class FilterReflex < ApplicationReflex | |
include Filterable | |
def filter | |
resource, param = element.dataset.to_h.fetch_values(:resource, :param) | |
value = element.dataset.value || element.value | |
if element["role"] == "checkbox" | |
if filter_for(resource, param).is_a? Array | |
if filter_for(resource, param).include? value | |
filter_for(resource, param).delete value | |
else | |
filter_for(resource, param) << value | |
end | |
else | |
set_filter_for!(resource, param, !filter_for(resource, param)) | |
end | |
else | |
set_filter_for!(resource, param, value) | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/filters/embed_filter.rb | |
class EmbedFilter < BaseFilter | |
attribute :embeddable_type, default: %w[MediaAsset OEmbedLink] # cannot use type: :array here :-( | |
def apply!(chain) | |
chain.where(embeddable_type: embeddable_type) if embeddable_type.present? | |
chain | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def filter_active_for?(resource, param, value=true) | |
filter = session.fetch(:filters, {}).fetch(resource, {}).fetch(param, []) | |
return filter.include?(value) if filter.is_a?(Enumerable) | |
filter == value | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/boards/index.html.erb --> | |
<%= text_field_tag "Search", | |
session[:filters]["Board"]["title"], | |
placeholder: "Search for a board", | |
data: {reflex: "debounced:input->Filter#filter", resource: "Board", param: "query"}, | |
%> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<button type="button" | |
role="checkbox" | |
data-reflex="click->Filter#filter" | |
data-resource="HistoryEntry" | |
data-param="show_all" | |
> | |
<span class="sr-only">Use setting</span> | |
<span aria-hidden="true" class="<%= filter_active_for?("HistoryEntry", "show_all") ? "translate-x-5" : "translate-x-0" %> ..."></span> | |
</button> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="flex items-center"> | |
<button type="button" | |
role="checkbox" | |
data-reflex="click->Filter#filter" | |
data-resource="Embed" | |
data-param="embeddable_type" | |
data-value="OEmbedLink" | |
> | |
<span class="sr-only">Use setting</span> | |
<span aria-hidden="true" class="<%= filter_active_for?("Embed", "embeddable_type", "OEmbedLink") ? "translate-x-5" : "translate-x-0" %> ..."></span> | |
</button> | |
<span class="ml-3" id="annual-billing-label"> | |
<span class="text-sm font-medium text-gray-900">Show Links</span> | |
</span> | |
</div> | |
<div class="flex items-center"> | |
<button type="button" | |
role="checkbox" | |
data-reflex="click->Filter#filter" | |
data-resource="Embed" | |
data-param="embeddable_type" | |
data-value="MediaAsset" | |
> | |
<span class="sr-only">Use setting</span> | |
<span aria-hidden="true" class="<%= filter_active_for?("Embed", "embeddable_type", "MediaAsset") ? "translate-x-5" : "translate-x-0" %> ..."></span> | |
</button> | |
<span class="ml-3" id="annual-billing-label"> | |
<span class="text-sm font-medium text-gray-900">Show Uploads</span> | |
</span> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/reflexes/filter_reflex.rb | |
class FilterReflex < ApplicationReflex | |
include Filterable | |
def filter | |
resource, param = element.dataset.to_h.fetch_values(:resource, :param) | |
value = element.dataset.value || element.value | |
set_filter_for!(resource, param, value) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/reflexes/filter_reflex.rb | |
class FilterReflex < ApplicationReflex | |
def filter | |
resource, param = element.dataset.to_h.fetch_values(:resource, :param) | |
value = element.dataset.value || element.value | |
if element["role"] == "checkbox" | |
# checkbox toggles elements in an array on and off | |
# %w[OEmbedLink MediaAsset] | |
if session[:filters][resource][param].is_a? Array | |
if session[:filters][resource][param].include? value | |
session[:filters][resource][param].delete value | |
else | |
session[:filters][resource][param] << value | |
end | |
# checkbox toggles a single value on and off | |
else | |
session[:filters][resource][param] = !session[:filters][resource][param] | |
end | |
else | |
session[:filters][resource][param] = value | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/concerns/filterable.rb | |
module Filterable | |
# ... | |
def filter_active_for?(resource, attribute, value=true) | |
filter = filter_for(resource) | |
filter.active_for?(attribute, value) | |
end | |
private | |
def filter_for(resource) | |
"#{resource}Filter".constantize.new(session) | |
end | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Filterable | |
extend ActiveSupport::Concern | |
private | |
def filter_for(resource, param) | |
session.fetch(:filters, {}).fetch(resource, {}).fetch(param, []) | |
end | |
def set_filter_for!(resource, param, value) | |
session[:filters] ||= {} | |
session[:filters][resource] ||= {} | |
session[:filters][resource][param] = value if (self.class.ancestors.include? StimulusReflex::Reflex || filter_for(resource, param).blank?) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/boards_controller.rb | |
class BoardsController < ApplicationController | |
# ... | |
def index | |
session[:filters] ||= {} | |
session[:filters]["Board"] ||= {"query" => ""} | |
query = session[:filters]["Board"]["query"] | |
@boards = current_user.boards.order(:created_at) | |
@boards = @boards.search(query) if query.present? | |
end | |
def show | |
session[:filters] ||= {} | |
session[:filters]["Embed"] ||= {"embeddable_type" => %w[MediaAsset OEmbedLink]} | |
@embed = @board.embeds.build | |
@embed_import = EmbedImport.new(board: @board) | |
@embeds = @board.embeds.where(session[:filters]["Embed"]) | |
end | |
# ... | |
end | |
# app/controllers/embed_controller.rb | |
class EmbedsController < ApplicationController | |
# ... | |
def show | |
session[:filters] ||= {} | |
session[:filters]["HistoryEntry"] ||= {"show_all" => false} | |
@comment ||= Comment.new(user: current_user) | |
@comment.build_history_entry(embed: @embed) | |
@history_entries = @embed.history_entries.includes(:entryable) | |
@history_entries = @history_entries.with_reactions unless filter_for("HistoryEntry", "show_all") | |
end | |
# ... | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# db/migrate/20210208120653_create_media_assets.rb | |
class CreateMediaAssets < ActiveRecord::Migration[6.1] | |
def change | |
create_table :media_assets do |t| | |
t.string :title | |
t.timestamps | |
end | |
end | |
end | |
# app/models/media_asset.rb | |
class MediaAsset < ApplicationRecord | |
include Embeddable | |
validates :title, presence: true | |
has_one_attached :media_file | |
def embed_code | |
"<audio controls><source src=\"#{Rails.application.routes.url_helpers.rails_blob_path(media_file, only_path: true)}\" type=\"audio/mp3\"></audio>".html_safe | |
end | |
end | |
# app/models/embed.rb | |
class Embed < ApplicationRecord | |
# ... | |
# ๐ add MediaAsset to the list of embeddable types | |
delegated_type :embeddable, types: %w(OEmbedLink MediaAsset) | |
# ๐ initialize MediaAsset correctly | |
after_initialize do | |
next if persisted? | |
if input&.start_with? "http" | |
self.embeddable = OEmbedLink.new(url: input) | |
else | |
self.embeddable = MediaAsset.new(title: input) | |
end | |
end | |
def title | |
self[:title] || embeddable.title | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment