From 32b2b34f3683d8479fdf75e6687b27ffbc8ee829 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Sun, 22 Sep 2024 16:55:13 -0400 Subject: [PATCH 01/16] anonymous post button added --- .../partials/composer-formatting.tpl | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl diff --git a/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl b/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl new file mode 100644 index 0000000000..4a654b932c --- /dev/null +++ b/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl @@ -0,0 +1,82 @@ +
+ +
+ + + + + + {{{ if composer:showHelpTab }}} + + {{{ end }}} +
+
+ From fffb9f260c726ba49de62aa977f3d3d868aa4d04 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Sun, 22 Sep 2024 16:56:16 -0400 Subject: [PATCH 02/16] styling anonymous post button --- .../static/scss/composer.scss | 417 ++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 node_modules/nodebb-plugin-composer-default/static/scss/composer.scss diff --git a/node_modules/nodebb-plugin-composer-default/static/scss/composer.scss b/node_modules/nodebb-plugin-composer-default/static/scss/composer.scss new file mode 100644 index 0000000000..918ebf2ef5 --- /dev/null +++ b/node_modules/nodebb-plugin-composer-default/static/scss/composer.scss @@ -0,0 +1,417 @@ +.composer { + background-color: var(--bs-body-bg); + color: var(--bs-body-color); + z-index: $zindex-dropdown; + visibility: hidden; + padding: 0; + position: fixed; + bottom: 0; + top: 0; + right: 0; + left: 0; + + .switch { + position: relative ; + display: inline-block; + width: 37px; + height: 18px; + background-color: #9f9f9f; + border-radius: 20px; + } + + .switch::after { + content: ''; + position: absolute; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: white; + top: 1px; + left: 1px; + transition: all 0.2s; + } + + .checkbox:checked + .switch::after { + left: 20px; + } + .checkbox:checked + .switch { + background-color: #383839; + } + .checkbox { + display: none; + } + + + .mobile-navbar { + position: static; + min-height: 40px; + margin: 0; + + .btn-group { + flex-shrink: 0; + } + + button { + font-size: 20px; + } + + display: flex; + + .category-name-container, .title { + text-align: center; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + flex-grow: 2; + font-size: 16px; + line-height: inherit; + padding: 9px 5px; + margin: 0; + } + } + + .title-container { + > div[data-component="composer/handle"] { + flex: 0.33; + } + + .category-list-container { + + [component="category-selector"] { + .category-dropdown-menu { + max-height: 300px; + } + } + } + + .category-list { + padding: 0 2rem; + } + + .action-bar { + .dropdown-menu:empty { + & ~ .dropdown-toggle { + display: none; + } + } + } + } + + .formatting-bar { + .spacer { + &:before { + content: ' | '; + color: $gray-200; + } + } + } + + .tags-container { + [component="composer/tag/dropdown"] { + .dropdown-menu { + max-height: 400px; + overflow-y: auto; + } + + > button { + border: 0; + } + } + // if picking tags from taglist dropdown hide the input + &.haswhitelist .bootstrap-tagsinput { + input { + display: none; + } + } + .bootstrap-tagsinput { + background: transparent; + flex-grow: 1; + border: 0; + padding: 0; + box-shadow: none; + max-height: 80px; + overflow: auto; + + input { + &::placeholder{ + color: $input-placeholder-color; + } + color: $body-color; + font-size: 16px; + width: 50%; + @include media-breakpoint-down(md) { + width: 100%; + } + + + height: 28px; + padding: 4px 6px; + } + + .ui-autocomplete { + max-height: 350px; + overflow-x: hidden; + overflow-y: auto; + } + } + } + + .resizer { + background: linear-gradient(transparent, var(--bs-body-bg)); + margin-left: calc($spacer * -0.5); + padding-left: $spacer; + + .trigger { + cursor: ns-resize; + + .handle { + border-top-left-radius: 50%; + border-top-right-radius: 50%; + border-bottom: 0 !important; + } + } + } + + .minimize { + display: none; + position: absolute; + top: 0px; + right: 10px; + height: 0; + + @include pointer; + + .trigger { + position: relative; + display: block; + top: -20px; + right: 0px; + margin: 0 auto; + margin-left: 20px; + line-height: 26px; + @include transition(filter .15s linear); + + &:hover { + filter: invert(100%); + } + + i { + width: 32px; + height: 32px; + background: #333; + border: 1px solid #333; + border-radius: 50%; + + position: relative; + + color: #FFF; + font-size: 16px; + + &:before { + position: relative; + top: 25%; + } + } + } + } + + &.reply { + .title-container { + display: none; + } + } + + &.resizable.maximized { + .resizer { + top: 0 !important; + background: transparent; + + .trigger { + height: $spacer * 0.5; + + .handle { + border-top-left-radius: 0%; + border-top-right-radius: 0%; + border-bottom-left-radius: 50%; + border-bottom-right-radius: 50%; + border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; + } + + i { + &:before { + content: fa-content($fa-var-chevron-down); + } + } + } + } + } + + .draft-icon { + font-family: 'FontAwesome'; + color: $success; + opacity: 0; + + &::before { + content: fa-content($fa-var-save); + } + + &.active { + animation: draft-saved 3s ease; + } + } + + textarea { + resize: none; + } + + .preview { + padding: $input-padding-y $input-padding-x; + } +} + +.datetime-picker { + display: flex; + justify-content: center; + flex-direction: row; + min-width: 310px; + max-width: 310px; + margin: 0 auto; + + input { + flex: 3; + line-height: inherit; + } + + input + input { + border-left: none; + flex: 2; + } +} + +.modal.topic-scheduler { + z-index: 1070; + & + .modal-backdrop { + z-index: 1060; + } +} + +@keyframes draft-saved { + 0%, 100% { + opacity: 0; + } + + 15% { + opacity: 1; + } + + 30% { + opacity: 0.5; + } + + 45% { + opacity: 1; + } + + 85% { + opacity: 1; + } +} + +@keyframes pulse { + from { + transform: scale(1); + color: inherit; + } + 50% { + transform: scale(.9); + } + to { + transform: scale(1); + color: #00adff; + } +} + +@include media-breakpoint-down(lg) { + html.composing .composer { z-index: $zindex-modal; } +} + +@include media-breakpoint-down(sm) { + html.composing { + .composer { + height: 100%; + + .draft-icon { + position: absolute; + bottom: 1em; + right: 0em; + + &::after { + top: 7px; + } + } + + .preview-container { + max-width: initial; + } + } + + body { + padding-bottom: 0 !important; + } + } +} + +@include media-breakpoint-up(lg) { + html.composing { + .composer { + left: 15%; + width: 70%; + min-height: 400px; + + .resizer { + display: block; + } + + .minimize { + display: block; + } + } + } +} + +@include media-breakpoint-up(md) { + // without this formatting elements that are dropdowns are not visible on desktop. + // on mobile dropdowns use bottom-sheet and overflow is auto + .formatting-group { + overflow: visible!important; + } +} + +@import './zen-mode'; +@import './page-compose'; +@import './textcomplete'; + + +.skin-noskin, .skin-cosmo, .skin-flatly, +.skin-journal, .skin-litera, .skin-minty, .skin-pulse, +.skin-sandstone, .skin-sketchy, .skin-spacelab, .skin-united { + .composer { + color: var(--bs-secondary) !important; + background-color: var(--bs-light) !important; + } +} + +.skin-cerulean, .skin-lumen, .skin-lux, .skin-morph, +.skin-simplex, .skin-yeti, .skin-zephyr { + .composer { + color: var(--bs-body) !important; + background-color: var(--bs-light) !important; + } +} + +@include color-mode(dark) { + .skin-noskin .composer { + color: var(--bs-secondary)!important; + background-color: var(--bs-body-bg)!important; + } +} \ No newline at end of file From f00c65ee985d093cfd64effb46b8b3e1ecb92f72 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Tue, 24 Sep 2024 20:15:02 -0400 Subject: [PATCH 03/16] change username and displayname to anonymous (still need to correct the if statement to make sure button is actually on --- src/topics/posts.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/topics/posts.js b/src/topics/posts.js index 73eb29b9f9..d44b411263 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -12,6 +12,7 @@ const meta = require('../meta'); const plugins = require('../plugins'); const utils = require('../utils'); + const backlinkRegex = new RegExp(`(?:${nconf.get('url').replace('/', '\\/')}|\b|\\s)\\/topic\\/(\\d+)(?:\\/\\w+)?`, 'g'); module.exports = function (Topics) { @@ -107,11 +108,13 @@ module.exports = function (Topics) { if (!Array.isArray(postData) || !postData.length) { return []; } + console.log(uid); const pids = postData.map(post => post && post.pid); async function getPostUserData(field, method) { const uids = _.uniq(postData.filter(p => p && parseInt(p[field], 10) >= 0).map(p => p[field])); const userData = await method(uids); + return _.zipObject(uids, userData); } const [ @@ -140,11 +143,17 @@ module.exports = function (Topics) { postObj.replies = replies[i]; postObj.selfPost = parseInt(uid, 10) > 0 && parseInt(uid, 10) === postObj.uid; + // Username override for guests, if enabled if (meta.config.allowGuestHandles && postObj.uid === 0 && postObj.handle) { postObj.user.username = validator.escape(String(postObj.handle)); postObj.user.displayname = postObj.user.username; + } else { //later I want to add logic to check if the user has the anonymous toggle on!!! + postObj.user.username = "anonymous"; + postObj.user.displayname = "anonymous"; } + + } }); From 038b1647a3de045c709d5a1265a7f285516c3fb2 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Fri, 4 Oct 2024 17:22:16 -0400 Subject: [PATCH 04/16] adding anonymous as a field for posts --- src/posts/data.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/posts/data.js b/src/posts/data.js index 3a4d303ff5..0877164d2a 100644 --- a/src/posts/data.js +++ b/src/posts/data.js @@ -7,7 +7,7 @@ const utils = require('../utils'); const intFields = [ 'uid', 'pid', 'tid', 'deleted', 'timestamp', 'upvotes', 'downvotes', 'deleterUid', 'edited', - 'replies', 'bookmarks', + 'replies', 'bookmarks', 'anonymous' ]; module.exports = function (Posts) { @@ -42,6 +42,9 @@ module.exports = function (Posts) { Posts.getPostFields = async function (pid, fields) { const posts = await Posts.getPostsFields([pid], fields); + if (!fields.includes('anonymous')) { + fields.push('anonymous'); + } return posts ? posts[0] : null; }; From 71052b53098dc6aaba4a817ff17141dd36283e41 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Wed, 9 Oct 2024 22:17:07 -0400 Subject: [PATCH 05/16] adding anonymous attribute to payload --- src/api/topics.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/api/topics.js b/src/api/topics.js index 7a6cabf966..8cf1719207 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -50,12 +50,11 @@ topicsAPI.get = async function (caller, data) { return topic; }; -topicsAPI.create = async function (caller, data) { +topicsAPI.create = async function (caller, data) { if (!data) { throw new Error('[[error:invalid-data]]'); } - - const payload = { ...data }; + const payload = {...data, anonymous: data.anonymous || false}; payload.tags = payload.tags || []; apiHelpers.setDefaultPostData(caller, payload); const isScheduling = parseInt(data.timestamp, 10) > payload.timestamp; @@ -72,7 +71,6 @@ topicsAPI.create = async function (caller, data) { if (shouldQueue) { return await posts.addToQueue(payload); } - const result = await topics.post(payload); await topics.thumbs.migrate(data.uuid, result.topicData.tid); From 6fb48f12a2d7969bc60dcaa66e3836a87921186e Mon Sep 17 00:00:00 2001 From: Mia Li Date: Wed, 9 Oct 2024 22:19:15 -0400 Subject: [PATCH 06/16] creating isAnonymous variable to check before posting --- src/topics/posts.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/topics/posts.js b/src/topics/posts.js index d44b411263..94c5769e8a 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -1,6 +1,4 @@ - 'use strict'; - const _ = require('lodash'); const validator = require('validator'); const nconf = require('nconf'); @@ -105,10 +103,11 @@ module.exports = function (Topics) { } Topics.addPostData = async function (postData, uid) { + const isAnonymous = await posts.getPostField(postData, 'anonymous'); + console.log('anonymous', isAnonymous); if (!Array.isArray(postData) || !postData.length) { return []; } - console.log(uid); const pids = postData.map(post => post && post.pid); async function getPostUserData(field, method) { @@ -131,7 +130,7 @@ module.exports = function (Topics) { getPostReplies(postData, uid), Topics.addParentPosts(postData), ]); - + postData.forEach((postObj, i) => { if (postObj) { postObj.user = postObj.uid ? userData[postObj.uid] : { ...userData[postObj.uid] }; @@ -142,17 +141,17 @@ module.exports = function (Topics) { postObj.votes = postObj.votes || 0; postObj.replies = replies[i]; postObj.selfPost = parseInt(uid, 10) > 0 && parseInt(uid, 10) === postObj.uid; + // Username override for guests, if enabled if (meta.config.allowGuestHandles && postObj.uid === 0 && postObj.handle) { postObj.user.username = validator.escape(String(postObj.handle)); postObj.user.displayname = postObj.user.username; - } else { //later I want to add logic to check if the user has the anonymous toggle on!!! + } else if (isAnonymous){ postObj.user.username = "anonymous"; postObj.user.displayname = "anonymous"; } - } }); @@ -161,6 +160,7 @@ module.exports = function (Topics) { posts: postData, uid: uid, }); + return result.posts; }; From d7d9caa815b3b9d08ddde6300ff1eb5e396e62f5 Mon Sep 17 00:00:00 2001 From: Mia Li Date: Wed, 9 Oct 2024 23:32:41 -0400 Subject: [PATCH 07/16] attempting to update post api --- .../static/templates/partials/composer-formatting.tpl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl b/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl index 4a654b932c..5ad195e416 100644 --- a/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl +++ b/node_modules/nodebb-plugin-composer-default/static/templates/partials/composer-formatting.tpl @@ -60,11 +60,13 @@
- + +