Add basic template for quote list
authorCyperghost <olaf_schmitz_1@t-online.de>
Thu, 19 Dec 2024 11:39:28 +0000 (12:39 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 8 Jan 2025 16:25:19 +0000 (17:25 +0100)
ts/WoltLabSuite/Core/Api/Messages/Author.ts
ts/WoltLabSuite/Core/Api/Messages/RenderQuote.ts
ts/WoltLabSuite/Core/Component/Quote/List.ts
ts/WoltLabSuite/Core/Component/Quote/Storage.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Component/Quote/List.js
wcfsetup/install/files/lib/system/endpoint/controller/core/messages/GetMessageAuthor.class.php
wcfsetup/install/files/lib/system/endpoint/controller/core/messages/RenderQuote.class.php

index 8a850bc06f1313dc6196d53e0ae1abb1d7a5ba27..2285cd63b646ed44501029c4280ff38c4279b09a 100644 (file)
@@ -15,7 +15,8 @@ type Response = {
   objectID: number;
   authorID: number;
   author: string;
-  time: number;
+  time: string;
+  title: string;
   link: string;
   avatar: string;
 };
index 11fda558e13dc6f534ee24907c255dbb7e0db764..85195f947447339e024b2e267f866b80f223418d 100644 (file)
@@ -15,8 +15,9 @@ type Response = {
   objectID: number;
   authorID: number;
   author: string;
-  time: number;
+  time: string;
   link: string;
+  title: string;
   avatar: string;
   message: string;
 };
index b047baacf7b33ec93e838a4080d76479b033ffc7..83ff19aa222f53b1bae7372d81fe80793514f4a7 100644 (file)
@@ -13,7 +13,8 @@ import type { CKEditor } from "WoltLabSuite/Core/Component/Ckeditor";
 import { getTabMenu } from "WoltLabSuite/Core/Component/Message/MessageTabMenu";
 import { getPhrase } from "WoltLabSuite/Core/Language";
 import { setActiveEditor } from "WoltLabSuite/Core/Component/Quote/Message";
-import { getQuotes } from "WoltLabSuite/Core/Component/Quote/Storage";
+import { getQuotes, getMessage } from "WoltLabSuite/Core/Component/Quote/Storage";
+import DomUtil from "WoltLabSuite/Core/Dom/Util";
 
 const quoteLists = new Map<string, QuoteList>();
 
@@ -40,7 +41,54 @@ class QuoteList {
   public renderQuotes(): void {
     this.#container.innerHTML = "";
 
-    for (const [, quotes] of getQuotes()) {
+    for (const [key, quotes] of getQuotes()) {
+      const message = getMessage(key)!;
+
+      // TODO escape values
+      // TODO create web components???
+      this.#container.append(
+        DomUtil.createFragmentFromHtml(`<article class="message messageReduced jsInvalidQuoteTarget">
+  <div class="messageContent">
+    <header class="messageHeader">
+      <div class="box32 messageHeaderWrapper">
+        <!-- TODO load real avatar -->
+        <span><img src="${window.WCF_PATH}images/avatars/avatar-default.svg" alt="" class="userAvatarImage" style="width: 32px; height: 32px"></span>
+        <div class="messageHeaderBox">
+          <h2 class="messageTitle">
+            <a href="${message.link}">${message.title}</a>
+          </h2>
+          <ul class="messageHeaderMetaData">
+            <!-- TODO add link to author profile -->
+            <li><span class="username">${message.author}</span></li>
+            <li><span class="messagePublicationTime"><woltlab-core-date-time date="${message.time}">${message.time}</woltlab-core-date-time></span></li>
+          </ul>
+        </div>
+      </div>
+    </header>
+    <div class="messageBody">
+      <div class="messageText">
+        <ul class="messageQuoteItemList">
+        ${Array.from(quotes)
+          .map(
+            (quote) => `<li>
+  <span>
+    <input type="checkbox" value="1" class="jsCheckbox">
+    <button type="button" class="jsTooltip jsInsertQuote" title="${getPhrase("wcf.message.quote.insertQuote")}">
+    </button>
+  </span>
+  
+  <div class="jsQuote">
+    ${quote}
+  </div>
+</li>`,
+          )
+          .join("")}
+        </ul>
+      </div>
+    </div>
+  </div>
+</article>`),
+      );
       // TODO render quotes
     }
 
index 78b74ba8540f1282c9ea48b976f321932f801fba..788894b3046ccbb3ebc588cc2ee485e5bdf0e7c3 100644 (file)
@@ -14,7 +14,8 @@ import { messageAuthor } from "WoltLabSuite/Core/Api/Messages/Author";
 
 interface Message {
   objectID: number;
-  time: number;
+  time: string;
+  title: string;
   link: string;
   authorID: number;
   author: string;
@@ -50,6 +51,7 @@ export async function saveFullQuote(objectType: string, objectClassName: string,
     {
       objectID: result.value.objectID,
       time: result.value.time,
+      title: result.value.title,
       link: result.value.link,
       authorID: result.value.authorID,
       author: result.value.author,
@@ -78,6 +80,12 @@ export function getQuotes(): Map<string, Set<string>> {
   return getStorage().quotes;
 }
 
+export function getMessage(objectType: string, objectId?: number): Message | undefined {
+  const key = objectId ? getKey(objectType, objectId) : objectType;
+
+  return getStorage().messages.get(key);
+}
+
 function getStorage(): StorageData {
   const data = window.localStorage.getItem(STORAGE_KEY);
   if (data === null) {
index a7a080d342547328bf643b802e577121e14703b0..9cb14f1db32f76cf4a03f598659f51b99d55af1f 100644 (file)
@@ -7,11 +7,12 @@
  * @since 6.2
  * @woltlabExcludeBundle tiny
  */
-define(["require", "exports", "WoltLabSuite/Core/Component/Ckeditor/Event", "WoltLabSuite/Core/Component/Message/MessageTabMenu", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/Component/Quote/Message", "WoltLabSuite/Core/Component/Quote/Storage"], function (require, exports, Event_1, MessageTabMenu_1, Language_1, Message_1, Storage_1) {
+define(["require", "exports", "tslib", "WoltLabSuite/Core/Component/Ckeditor/Event", "WoltLabSuite/Core/Component/Message/MessageTabMenu", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/Component/Quote/Message", "WoltLabSuite/Core/Component/Quote/Storage", "WoltLabSuite/Core/Dom/Util"], function (require, exports, tslib_1, Event_1, MessageTabMenu_1, Language_1, Message_1, Storage_1, Util_1) {
     "use strict";
     Object.defineProperty(exports, "__esModule", { value: true });
     exports.getQuoteList = getQuoteList;
     exports.setup = setup;
+    Util_1 = tslib_1.__importDefault(Util_1);
     const quoteLists = new Map();
     class QuoteList {
         #container;
@@ -31,7 +32,51 @@ define(["require", "exports", "WoltLabSuite/Core/Component/Ckeditor/Event", "Wol
         }
         renderQuotes() {
             this.#container.innerHTML = "";
-            for (const [, quotes] of (0, Storage_1.getQuotes)()) {
+            for (const [key, quotes] of (0, Storage_1.getQuotes)()) {
+                const message = (0, Storage_1.getMessage)(key);
+                // TODO escape values
+                // TODO create web components???
+                this.#container.append(Util_1.default.createFragmentFromHtml(`<article class="message messageReduced jsInvalidQuoteTarget">
+  <div class="messageContent">
+    <header class="messageHeader">
+      <div class="box32 messageHeaderWrapper">
+        <!-- TODO load real avatar -->
+        <span><img src="${window.WCF_PATH}images/avatars/avatar-default.svg" alt="" class="userAvatarImage" style="width: 32px; height: 32px"></span>
+        <div class="messageHeaderBox">
+          <h2 class="messageTitle">
+            <a href="${message.link}">${message.title}</a>
+          </h2>
+          <ul class="messageHeaderMetaData">
+            <!-- TODO add link to author profile -->
+            <li><span class="username">${message.author}</span></li>
+            <li><span class="messagePublicationTime"><woltlab-core-date-time date="${message.time}">${message.time}</woltlab-core-date-time></span></li>
+          </ul>
+        </div>
+      </div>
+    </header>
+    <div class="messageBody">
+      <div class="messageText">
+        <ul class="messageQuoteItemList">
+        ${Array.from(quotes)
+                    .map((quote) => `<li>
+  <span>
+    <input type="checkbox" value="1" class="jsCheckbox">
+    <button type="button" class="jsTooltip jsInsertQuote" title="${(0, Language_1.getPhrase)("wcf.message.quote.insertQuote")}">
+    </button>
+  </span>
+  
+  <div class="jsQuote">
+  <label for="quote_{@$quoteID}">
+    ${quote}
+  </label>
+  </div>
+</li>`)
+                    .join("")}
+        </ul>
+      </div>
+    </div>
+  </div>
+</article>`));
                 // TODO render quotes
             }
             if (this.#container.hasChildNodes()) {
index e378a79dd86d9f6629a3075c48c42b40e1da4ea7..a6022686fcb362f41c24f367914dd9d3fc6ffb26 100644 (file)
@@ -37,8 +37,9 @@ final class GetMessageAuthor implements IController
                 "objectID" => $object->getObjectID(),
                 "authorID" => $userProfile->getUserID(),
                 "author" => $userProfile->getUsername(),
+                "title" => $object->getTitle(),
                 "avatar" => $userProfile->getAvatar()->getURL(),
-                "time" => $object->getTime(),
+                "time" => (new \DateTime('@' . $object->getTime()))->format("c"),
                 "link" => $object->getLink(),
             ],
             200,
index e6868a7fbf936f214859acc882455158bdab4668..21c1103cb2ceff6e6d6428de308ced7f9a701e51 100644 (file)
@@ -40,7 +40,8 @@ final class RenderQuote implements IController
                 "authorID" => $userProfile->getUserID(),
                 "author" => $userProfile->getUsername(),
                 "avatar" => $userProfile->getAvatar()->getURL(),
-                "time" => $object->getTime(),
+                "time" => (new \DateTime('@' . $object->getTime()))->format("c"),
+                "title" => $object->getTitle(),
                 "link" => $object->getLink(),
                 "message" => $parameters->fullQuote ? $this->renderFullQuote($object) : ""
             ],