This commit is contained in:
15
app/helpers/application_helper.rb
Normal file
15
app/helpers/application_helper.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module ApplicationHelper
|
||||
def hide_from_user_style_tag
|
||||
tag.style(<<~CSS.html_safe)
|
||||
[data-hide-from-user-id="#{Current.user.id}"] {
|
||||
display: none!important;
|
||||
}
|
||||
CSS
|
||||
end
|
||||
|
||||
def custom_styles_tag
|
||||
if custom_styles = Current.account&.custom_styles
|
||||
tag.style(custom_styles.to_s.html_safe, data: { turbo_track: "reload" })
|
||||
end
|
||||
end
|
||||
end
|
||||
38
app/helpers/arrangement_helper.rb
Normal file
38
app/helpers/arrangement_helper.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
module ArrangementHelper
|
||||
def arrangement_tag(book, **, &)
|
||||
tag.div data: {
|
||||
controller: "arrangement reading-progress",
|
||||
arrangement_cursor_class: "arrangement-cursor",
|
||||
arrangement_selected_class: "arrangement-selected",
|
||||
arrangement_placeholder_class: "arrangement-placeholder",
|
||||
arrangement_adding_mode_class: "arrangement--adding",
|
||||
arrangement_move_mode_class: "arrangement-move-mode",
|
||||
arrangement_url_value: book_leaves_moves_url(book),
|
||||
reading_progress_book_id_value: book.id,
|
||||
reading_progress_last_read_class: "toc__leaf--last-read"
|
||||
}, **, &
|
||||
end
|
||||
|
||||
def arrangement_actions
|
||||
actions = {
|
||||
"click": "click",
|
||||
"dragstart": "dragStart",
|
||||
"dragover": "dragOver:prevent",
|
||||
"dragend": "dragEnd",
|
||||
"drop": "drop",
|
||||
"keydown.up": "moveBefore",
|
||||
"keydown.right": "moveAfter",
|
||||
"keydown.down": "moveAfter",
|
||||
"keydown.left": "moveBefore",
|
||||
"keydown.shift+up": "moveBefore",
|
||||
"keydown.shift+right": "moveAfter",
|
||||
"keydown.shift+down": "moveAfter",
|
||||
"keydown.shift+left": "moveBefore",
|
||||
"keydown.space": "toggleMoveMode",
|
||||
"keydown.enter": "applyMoveMode",
|
||||
"keydown.esc": "cancelMoveMode"
|
||||
}
|
||||
|
||||
actions.map { |action, target| "#{action}->arrangement##{target}" }.join(" ")
|
||||
end
|
||||
end
|
||||
6
app/helpers/books/editing_helper.rb
Normal file
6
app/helpers/books/editing_helper.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Books::EditingHelper
|
||||
def editing_mode_toggle_switch(leaf, checked:)
|
||||
target_url = checked ? leafable_slug_path(leaf) : edit_leafable_path(leaf)
|
||||
render "books/edit_mode", target_url: target_url, checked: checked
|
||||
end
|
||||
end
|
||||
67
app/helpers/books_helper.rb
Normal file
67
app/helpers/books_helper.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
module BooksHelper
|
||||
def book_toc_tag(book, &)
|
||||
tag.ol class: "toc", tabindex: 0,
|
||||
data: {
|
||||
controller: "arrangement",
|
||||
action: arrangement_actions,
|
||||
arrangement_cursor_class: "arrangement-cursor",
|
||||
arrangement_selected_class: "arrangement-selected",
|
||||
arrangement_placeholder_class: "arrangement-placeholder",
|
||||
arrangement_move_mode_class: "arrangement-move-mode",
|
||||
arrangement_url_value: book_leaves_moves_url(book)
|
||||
}, &
|
||||
end
|
||||
|
||||
def book_part_create_button(book, kind, **, &)
|
||||
url = url_for [ book, kind.new ]
|
||||
|
||||
button_to url, class: "btn btn--plain txt-medium fill-transparent disable-when-arranging disable-when-deleting", draggable: true,
|
||||
data: {
|
||||
action: "dragstart->arrangement#dragStartCreate dragend->arrangement#dragEndCreate",
|
||||
arrangement_url_param: url
|
||||
}, **, &
|
||||
end
|
||||
|
||||
def link_to_first_leafable(leaves)
|
||||
if first_leaf = leaves.first
|
||||
link_to leafable_slug_path(first_leaf), data: hotkey_data_attributes("right"), class: "disable-when-arranging", hidden: true do
|
||||
tag.span(class: "btn") do
|
||||
image_tag("arrow-right.svg", aria: { hidden: true }, size: 24) + tag.span("Start reading", class: "for-screen-reader")
|
||||
end + tag.span(first_leaf.title, class: "overflow-ellipsis")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_previous_leafable(leaf, hotkey: true, for_edit: false)
|
||||
if previous_leaf = leaf.previous
|
||||
path = for_edit ? edit_leafable_path(previous_leaf) : leafable_slug_path(previous_leaf)
|
||||
link_to path, data: hotkey_data_attributes("left", enabled: hotkey), class: "btn" do
|
||||
image_tag("arrow-left.svg", aria: { hidden: true }, size: 24) + tag.span("Previous: #{ previous_leaf.title }", class: "for-screen-reader")
|
||||
end
|
||||
else
|
||||
link_to book_slug_path(leaf.book), data: hotkey_data_attributes("left", enabled: hotkey), class: "btn" do
|
||||
image_tag("arrow-left.svg", aria: { hidden: true }, size: 24) + tag.span("Table of contents: #{ leaf.book.title }", class: "for-screen-reader")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_next_leafable(leaf, hotkey: true, for_edit: false)
|
||||
if next_leaf = leaf.next
|
||||
path = for_edit ? edit_leafable_path(next_leaf) : leafable_slug_path(next_leaf)
|
||||
link_to path, data: hotkey_data_attributes("right", enabled: hotkey), class: "btn txt-medium min-width" do
|
||||
tag.span("Next: #{next_leaf.title }", class: "overflow-ellipsis") + image_tag("arrow-right.svg", aria: { hidden: true }, size: 24)
|
||||
end
|
||||
else
|
||||
link_to book_slug_path(leaf.book), data: hotkey_data_attributes("right", enabled: hotkey), class: "btn txt-medium" do
|
||||
tag.span("Table of contents: #{leaf.book.title }", class: "overflow-ellipsis") + image_tag("arrow-reverse.svg", aria: { hidden: true }, size: 24)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def hotkey_data_attributes(key, enabled: true)
|
||||
if enabled
|
||||
{ controller: "hotkey", action: "keydown.#{key}@document->hotkey#click touch:swipe-#{key}@window->hotkey#click" }
|
||||
end
|
||||
end
|
||||
end
|
||||
8
app/helpers/forms_helper.rb
Normal file
8
app/helpers/forms_helper.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
module FormsHelper
|
||||
def auto_submit_form_with(**attributes, &)
|
||||
data = attributes.delete(:data) || {}
|
||||
data[:controller] = "auto-submit #{data[:controller]}".strip
|
||||
|
||||
form_with **attributes, data: data, &
|
||||
end
|
||||
end
|
||||
22
app/helpers/invitations_helper.rb
Normal file
22
app/helpers/invitations_helper.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
module InvitationsHelper
|
||||
def button_to_copy_to_clipboard(url, &)
|
||||
tag.button class: "btn", data: {
|
||||
controller: "copy-to-clipboard", action: "copy-to-clipboard#copy",
|
||||
copy_to_clipboard_success_class: "btn--success", copy_to_clipboard_content_value: url
|
||||
}, &
|
||||
end
|
||||
|
||||
def web_share_button(url, title, text, &)
|
||||
tag.button class: "btn", hidden: true, data: {
|
||||
controller: "web-share", action: "web-share#share",
|
||||
web_share_url_value: url,
|
||||
web_share_text_value: text,
|
||||
web_share_title_value: title
|
||||
}, &
|
||||
end
|
||||
|
||||
def qr_code_image(url)
|
||||
qr_code_link = QrCodeLink.new(url)
|
||||
image_tag qr_code_path(qr_code_link.signed), class: "qr-code center", alt: "QR Code"
|
||||
end
|
||||
end
|
||||
29
app/helpers/leaves_helper.rb
Normal file
29
app/helpers/leaves_helper.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
module LeavesHelper
|
||||
def leaf_item_tag(leaf, **, &)
|
||||
tag.li class: "arrangement__item toc__leaf toc__leaf--#{leaf.leafable_name}",
|
||||
id: dom_id(leaf),
|
||||
data: {
|
||||
id: leaf.id,
|
||||
arrangement_target: "item"
|
||||
}, **, &
|
||||
end
|
||||
|
||||
def leaf_nav_tag(leaf, **, &)
|
||||
tag.nav data: {
|
||||
controller: "reading-tracker",
|
||||
reading_tracker_book_id_value: leaf.book_id,
|
||||
reading_tracker_leaf_id_value: leaf.id
|
||||
}, **, &
|
||||
end
|
||||
|
||||
def leafable_edit_form(leafable, **, &)
|
||||
form_with model: leafable, url: leafable_path(leafable.leaf), method: :put, format: :html,
|
||||
data: {
|
||||
controller: "autosave",
|
||||
action: "autosave#submit:prevent input@document->autosave#change house-md:change->autosave#change",
|
||||
autosave_clean_class: "clean",
|
||||
autosave_dirty_class: "dirty",
|
||||
autosave_saving_class: "saving"
|
||||
}, **, &
|
||||
end
|
||||
end
|
||||
14
app/helpers/pages_helper.rb
Normal file
14
app/helpers/pages_helper.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
module PagesHelper
|
||||
def word_count(content)
|
||||
return if content.blank?
|
||||
pluralize number_with_delimiter(content.split.size), "word"
|
||||
end
|
||||
|
||||
def page_title(leaf, book)
|
||||
[ leaf.title, book.title, book.author ].reject(&:blank?).to_sentence(two_words_connector: " · ", words_connector: " · ", last_word_connector: " · ")
|
||||
end
|
||||
|
||||
def sanitize_content(content)
|
||||
sanitize content, scrubber: HtmlScrubber.new
|
||||
end
|
||||
end
|
||||
2
app/helpers/pictures_helper.rb
Normal file
2
app/helpers/pictures_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module PicturesHelper
|
||||
end
|
||||
2
app/helpers/sections_helper.rb
Normal file
2
app/helpers/sections_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module SectionsHelper
|
||||
end
|
||||
36
app/helpers/translations_helper.rb
Normal file
36
app/helpers/translations_helper.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
module TranslationsHelper
|
||||
TRANSLATIONS = {
|
||||
book_author: { "🇺🇸": "Author", "🇪🇸": "Autor", "🇫🇷": "Auteur", "🇮🇳": "लेखक", "🇩🇪": "Autor", "🇧🇷": "Autor" },
|
||||
book_subtitle: { "🇺🇸": "Subtitle", "🇪🇸": "Subtítulo", "🇫🇷": "Sous-titre", "🇮🇳": "उपशीर्षक", "🇩🇪": "Untertitel", "🇧🇷": "Subtítulo" },
|
||||
book_title: { "🇺🇸": "Book title", "🇪🇸": "Título del libro", "🇫🇷": "Titre du livre", "🇮🇳": "पुस्तक का शीर्षक", "🇩🇪": "Buchtitel", "🇧🇷": "Título do livro" },
|
||||
custom_styles: { "🇺🇸": "Add custom CSS styles. Use Caution: you could break things.", "🇪🇸": "Agrega estilos CSS personalizados. Usa precaución: podrías romper cosas.", "🇫🇷": "Ajoutez des styles CSS personnalisés. Utilisez avec précaution : vous pourriez casser des choses.", "🇮🇳": "कस्टम CSS स्टाइल जोड़ें। सावधानी बरतें: आप चीज़ों को तोड़ सकते हैं।", "🇩🇪": "Fügen Sie benutzerdefinierte CSS-Stile hinzu. Vorsicht: Sie könnten Dinge kaputt machen.", "🇧🇷": "Adicione estilos CSS personalizados. Use com cuidado: você pode quebrar coisas." },
|
||||
email_address: { "🇺🇸": "Enter your email address", "🇪🇸": "Introduce tu correo electrónico", "🇫🇷": "Entrez votre adresse courriel", "🇮🇳": "अपना ईमेल पता दर्ज करें", "🇩🇪": "Geben Sie Ihre E-Mail-Adresse ein", "🇧🇷": "Insira seu endereço de email" },
|
||||
password: { "🇺🇸": "Enter your password", "🇪🇸": "Introduce tu contraseña", "🇫🇷": "Saisissez votre mot de passe", "🇮🇳": "अपना पासवर्ड दर्ज करें", "🇩🇪": "Geben Sie Ihr Passwort ein", "🇧🇷": "Insira sua senha" },
|
||||
picture_caption: { "🇺🇸": "Picture caption", "🇪🇸": "Subtítulo de la imagen", "🇫🇷": "Légende de l'image", "🇮🇳": "चित्र का कैप्शन", "🇩🇪": "Bildunterschrift", "🇧🇷": "Legenda da imagem" },
|
||||
transfer_session: { "🇺🇸": "Share to get them back into their account", "🇪🇸": "Comparte para que vuelvan a acceder a su cuenta", "🇫🇷": "Partagez pour les reconnecter à leur compte", "🇮🇳": "उन्हें उनके खाते में वापस लाने के लिए साझा करें", "🇩🇪": "Teilen, um ihnen den Zugang zu ihrem Konto zu ermöglichen", "🇧🇷": "Compartilhe para que eles voltem a acessar sua conta" },
|
||||
transfer_session_self: { "🇺🇸": "Link to automatically log in on another device", "🇪🇸": "Enlace para iniciar sesión automáticamente en otro dispositivo", "🇫🇷": "Lien pour se connecter automatiquement sur un autre appareil", "🇮🇳": "किसी अन्य डिवाइस पर स्वचालित रूप से लॉग इन करने के लिए लिंक", "🇩🇪": "Link, um sich automatisch auf einem anderen Gerät anzumelden", "🇧🇷": "Link para fazer login automaticamente em outro dispositivo" },
|
||||
user_name: { "🇺🇸": "Enter your name", "🇪🇸": "Introduce tu nombre", "🇫🇷": "Entrez votre nom", "🇮🇳": "अपना नाम दर्ज करें", "🇩🇪": "Geben Sie Ihren Namen ein", "🇧🇷": "Insira seu nome" },
|
||||
update_password: { "🇺🇸": "Change password", "🇪🇸": "Cambiar contraseña", "🇫🇷": "Changer le mot de passe", "🇮🇳": "पासवर्ड बदलें", "🇩🇪": "Passwort ändern", "🇧🇷": "Alterar senha" }
|
||||
}
|
||||
|
||||
def translations_for(translation_key)
|
||||
tag.dl(class: "language-list") do
|
||||
TRANSLATIONS[translation_key].map do |language, translation|
|
||||
concat tag.dt(language)
|
||||
concat tag.dd(translation, class: "margin-none")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def translation_button(translation_key)
|
||||
tag.div(class: "position-relative", data: { controller: "popover", action: "keydown.esc->popover#close click@document->popover#closeOnClickOutside", popover_orientation_top_class: "popover-orientation-top" }) do
|
||||
tag.button(type: "button", class: "btn", tabindex: -1, data: { action: "popover#toggle" }) do
|
||||
concat image_tag("globe.svg", size: 20, role: "presentation", class: "color-icon")
|
||||
concat tag.span("Translate", class: "for-screen-reader")
|
||||
end +
|
||||
tag.dialog(class: "lanuage-list-menu popover shadow", data: { popover_target: "menu" }) do
|
||||
translations_for(translation_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
7
app/helpers/turbo_stream_actions_helper.rb
Normal file
7
app/helpers/turbo_stream_actions_helper.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module TurboStreamActionsHelper
|
||||
def scroll_into_view(id, animation: nil)
|
||||
turbo_stream_action_tag :scroll_into_view, target: id, animation: animation
|
||||
end
|
||||
end
|
||||
|
||||
Turbo::Streams::TagBuilder.prepend TurboStreamActionsHelper
|
||||
5
app/helpers/version_helper.rb
Normal file
5
app/helpers/version_helper.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
module VersionHelper
|
||||
def version_badge
|
||||
tag.span(Rails.application.config.app_version, class: "product__version-badge")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user