From 90edfec0a9633af4f8aabdbb345319ef6904d496 Mon Sep 17 00:00:00 2001 From: Cinder Date: Mon, 27 Jan 2025 07:07:11 -0800 Subject: [PATCH] [Posts] Add a wiki excerpt to the search page (#861) --- app/controllers/posts_controller.rb | 15 +++- app/javascript/packs/application.js | 2 + app/javascript/src/javascripts/post_search.js | 24 +++++ .../src/javascripts/utility/storage.js | 3 + .../src/styles/specific/post_index.scss | 88 +++++++++++++++++++ .../posts/partials/index/_posts.html.erb | 10 ++- 6 files changed, 140 insertions(+), 2 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index f93529d00..843ee2dec 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -15,9 +15,22 @@ class PostsController < ApplicationController else @post_set = PostSets::Post.new(tag_query, params[:page], limit: params[:limit], random: params[:random]) @posts = PostsDecorator.decorate_collection(@post_set.posts) + + @query = tag_query.nil? ? [] : tag_query.strip.split(/ /, 2).compact_blank + if @query.length == 1 + @wiki_page = WikiPage.titled(@query[0]) + @wiki_text = @wiki_page.present? ? @wiki_page.body : "" + if @wiki_text.present? + @wiki_text = @wiki_text + .gsub(/thumb #\d+ ?/, "") + .strip + .truncate(512) + end + end + respond_with(@posts) do |format| format.json do - render json: @post_set.api_posts, root: 'posts' + render json: @post_set.api_posts, root: "posts" end format.atom end diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index b04f50f6d..b5a0cb670 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -34,6 +34,8 @@ importAll(require.context('../src/javascripts', true, /\.js(\.erb)?$/)); require.context("../../../public/images", true) +export { default as LStorage } from "../src/javascripts/utility/storage.js"; + export { default as Autocomplete } from '../src/javascripts/autocomplete.js.erb'; export { default as Blacklist } from '../src/javascripts/blacklists.js'; export { default as Blip } from '../src/javascripts/blips.js'; diff --git a/app/javascript/src/javascripts/post_search.js b/app/javascript/src/javascripts/post_search.js index cf98a1274..5b2505d20 100644 --- a/app/javascript/src/javascripts/post_search.js +++ b/app/javascript/src/javascripts/post_search.js @@ -1,9 +1,15 @@ +import LStorage from "./utility/storage"; + const PostSearch = {}; PostSearch.init = function () { $(".post-search").each((index, element) => { PostSearch.initialize_input($(element)); }); + + $(".wiki-excerpt").each((index, element) => { + PostSearch.initialize_wiki_preview($(element)); + }); }; PostSearch.initialize_input = function ($form) { @@ -27,6 +33,24 @@ PostSearch.initialize_input = function ($form) { $textarea.trigger("input"); }; +PostSearch.initialize_wiki_preview = function ($preview) { + let visible = LStorage.Posts.WikiExcerpt; + if (visible) + $preview.removeClass("hidden"); + console.log("init", visible); + + $($preview.find("a.wiki-excerpt-toggle")).on("click", (event) => { + event.preventDefault(); + + visible = !visible; + $preview.toggleClass("hidden", !visible); + LStorage.Posts.WikiExcerpt = visible; + console.log("state", visible); + + return false; + }); +}; + $(() => { PostSearch.init(); }); diff --git a/app/javascript/src/javascripts/utility/storage.js b/app/javascript/src/javascripts/utility/storage.js index 48be54ff9..f796134d4 100644 --- a/app/javascript/src/javascripts/utility/storage.js +++ b/app/javascript/src/javascripts/utility/storage.js @@ -82,6 +82,9 @@ LStorage.Posts = { /** @returns {number} ID of the user's selected set */ Set: ["set", 0], + + /** @returns {boolean} True if the wiki excerpt should be visible */ + WikiExcerpt: ["e6.posts.wiki", true], }; StorageUtils.bootstrapMany(LStorage.Posts); diff --git a/app/javascript/src/styles/specific/post_index.scss b/app/javascript/src/styles/specific/post_index.scss index 07bcec91e..497115070 100644 --- a/app/javascript/src/styles/specific/post_index.scss +++ b/app/javascript/src/styles/specific/post_index.scss @@ -26,6 +26,94 @@ #edit-dialog textarea { margin-bottom: 0.25em; } + + // Actual content area: + // posts and pagination + .post-index-gallery { + display: flex; + flex-flow: column; + gap: 1em; + + .wiki-excerpt { + display: flex; + flex-flow: column; + position: relative; + padding: 1em 1em 0; + gap: 0.5em; + + background: var(--color-section); + max-width: 60em; + + .wiki-excerpt-toggle { + position: absolute; + top: 0; + right: 0; + padding: 1em; + outline: none; + + transition: transform 0.25s; + + &::after { + @include font-awesome-icon; + content: unicode("f0d8"); + } + } + + .styled-dtext { + background: linear-gradient(to top, var(--color-section), var(--color-text)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + max-height: 10em; + overflow: hidden; + + transition: max-height 0.25s; + + // Disable links + pointer-events: none; + cursor: unset; + + a { + color: unset; + text-decoration: underline; + &::after { content: none; } + } + } + + .wiki-excerpt-readmore { + display: flex; + justify-content: center; + align-items: center; + + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 3em; + + // Makes the button appear in the middle of the animation + transition: visibility 0s 0.125s; + + span { + padding: 0.5em 1em; + background: var(--color-section); + border-radius: 6px; + } + } + + &.hidden{ + .wiki-excerpt-toggle { transform: rotate(-90deg); } + .styled-dtext { + max-height: 0; + } + .wiki-excerpt-readmore { visibility: hidden; } + } + } + + .paginator { + padding: 1em 0; + } + } } // 3. Sidebar diff --git a/app/views/posts/partials/index/_posts.html.erb b/app/views/posts/partials/index/_posts.html.erb index aa1d23826..ef5aa5225 100644 --- a/app/views/posts/partials/index/_posts.html.erb +++ b/app/views/posts/partials/index/_posts.html.erb @@ -1,4 +1,12 @@ -
+
+ <% if @wiki_text.present? %> + + <% end %>
<% if @posts.empty? %> <%= render "posts/blank" %>