78 lines
2.6 KiB
Ruby
78 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2014 - present Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
# Software Foundation, version 3 of the License.
|
|
#
|
|
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
module ContentNotices
|
|
NOTICE_ATTRIBUTES = %i[tag text variant link_text link_target should_show].freeze
|
|
|
|
class ContentNotice
|
|
attr_accessor(*NOTICE_ATTRIBUTES)
|
|
end
|
|
|
|
module ClassMethods
|
|
# opts must include:
|
|
# text: string (or Proc that returns string): text for the notice
|
|
# opts may optionally contain:
|
|
# variant: string: InstUI alert variant ('info', 'success', 'error', 'warning'; default is 'info')
|
|
# link_text: string (or Proc that returns string): text for a link that follows the notice
|
|
# link_target: string (or Proc that takes the context and returns a string): the target for said link
|
|
# should_show: Proc: callback that receives the context and user, and returns whether the notice should be displayed
|
|
# see course.rb for example usage
|
|
def define_content_notice(tag, opts)
|
|
notice = ContentNotice.new
|
|
NOTICE_ATTRIBUTES.each do |attr|
|
|
notice.instance_variable_set :"@#{attr}", opts[attr] if opts.include?(attr)
|
|
end
|
|
notice.tag ||= tag
|
|
@content_notices ||= {}
|
|
@content_notices[tag] = notice
|
|
end
|
|
|
|
def content_notices
|
|
@content_notices
|
|
end
|
|
end
|
|
|
|
def self.included(base)
|
|
base.extend(ClassMethods)
|
|
end
|
|
|
|
def cn_cache_key(tag)
|
|
["content_notice_present", tag, asset_string].cache_key
|
|
end
|
|
|
|
# add a notice to this context. if the notice with the given tag is already active for the context,
|
|
# its expiration time will be reset.
|
|
def add_content_notice(tag, expires_in = nil)
|
|
Rails.cache.write(cn_cache_key(tag), true, expires_in:)
|
|
end
|
|
|
|
# remove a notice from this context
|
|
def remove_content_notice(tag)
|
|
Rails.cache.delete(cn_cache_key(tag))
|
|
end
|
|
|
|
# return an array of content notices that should be shown to the user
|
|
def content_notices(user)
|
|
self.class.content_notices.select do |tag, notice|
|
|
Rails.cache.read(cn_cache_key(tag)) && (notice.should_show.nil? || notice.should_show.call(self, user))
|
|
end.values
|
|
end
|
|
end
|