From 1a333aabba759fb68449ead9c47e986f456e8c8c Mon Sep 17 00:00:00 2001
From: Sean King
Date: Tue, 7 Jun 2022 21:31:48 -0600
Subject: Add edit status functionality
---
src/App.js | 2 +
src/App.vue | 1 +
.../edit_status_modal/edit_status_modal.js | 75 ++++++++++++++++++
.../edit_status_modal/edit_status_modal.vue | 48 ++++++++++++
src/components/extra_buttons/extra_buttons.js | 13 ++++
src/components/extra_buttons/extra_buttons.vue | 11 +++
.../post_status_form/post_status_form.js | 45 ++++++++---
.../post_status_form/post_status_form.vue | 1 +
src/i18n/en.json | 2 +
src/main.js | 3 +
src/modules/api.js | 2 +
src/modules/editStatus.js | 25 ++++++
src/modules/statuses.js | 6 ++
src/services/api/api.service.js | 88 +++++++++++++++++++++-
.../entity_normalizer/entity_normalizer.service.js | 12 +++
.../status_poster/status_poster.service.js | 42 +++++++++++
16 files changed, 364 insertions(+), 12 deletions(-)
create mode 100644 src/components/edit_status_modal/edit_status_modal.js
create mode 100644 src/components/edit_status_modal/edit_status_modal.vue
create mode 100644 src/modules/editStatus.js
(limited to 'src')
diff --git a/src/App.js b/src/App.js
index f01f8788..6e0e34a8 100644
--- a/src/App.js
+++ b/src/App.js
@@ -11,6 +11,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
import MobileNav from './components/mobile_nav/mobile_nav.vue'
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
+import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
@@ -35,6 +36,7 @@ export default {
SettingsModal,
UserReportingModal,
PostStatusModal,
+ EditStatusModal,
GlobalNoticeList
},
data: () => ({
diff --git a/src/App.vue b/src/App.vue
index 5b448972..9484f993 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -52,6 +52,7 @@
+
diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js
new file mode 100644
index 00000000..14320d21
--- /dev/null
+++ b/src/components/edit_status_modal/edit_status_modal.js
@@ -0,0 +1,75 @@
+import PostStatusForm from '../post_status_form/post_status_form.vue'
+import Modal from '../modal/modal.vue'
+import statusPosterService from '../../services/status_poster/status_poster.service.js'
+import get from 'lodash/get'
+
+const EditStatusModal = {
+ components: {
+ PostStatusForm,
+ Modal
+ },
+ data () {
+ return {
+ resettingForm: false
+ }
+ },
+ computed: {
+ isLoggedIn () {
+ return !!this.$store.state.users.currentUser
+ },
+ modalActivated () {
+ return this.$store.state.editStatus.modalActivated
+ },
+ isFormVisible () {
+ return this.isLoggedIn && !this.resettingForm && this.modalActivated
+ },
+ params () {
+ return this.$store.state.editStatus.params || {}
+ }
+ },
+ watch: {
+ params (newVal, oldVal) {
+ if (get(newVal, 'repliedUser.id') !== get(oldVal, 'repliedUser.id')) {
+ this.resettingForm = true
+ this.$nextTick(() => {
+ this.resettingForm = false
+ })
+ }
+ },
+ isFormVisible (val) {
+ if (val) {
+ this.$nextTick(() => this.$el && this.$el.querySelector('textarea').focus())
+ }
+ }
+ },
+ methods: {
+ doEditStatus ({ status, spoilerText, sensitive, media, contentType, poll }) {
+ const params = {
+ store: this.$store,
+ statusId: this.$store.state.editStatus.params.statusId,
+ status,
+ spoilerText,
+ sensitive,
+ poll,
+ media,
+ contentType
+ }
+
+ return statusPosterService.editStatus(params)
+ .then((data) => {
+ return data
+ })
+ .catch((err) => {
+ console.error('Error editing status', err)
+ return {
+ error: err.message
+ }
+ })
+ },
+ closeModal () {
+ this.$store.dispatch('closeEditStatusModal')
+ }
+ }
+}
+
+export default EditStatusModal
diff --git a/src/components/edit_status_modal/edit_status_modal.vue b/src/components/edit_status_modal/edit_status_modal.vue
new file mode 100644
index 00000000..00dde7de
--- /dev/null
+++ b/src/components/edit_status_modal/edit_status_modal.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index dd45b6b9..9508a707 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -71,6 +71,19 @@ const ExtraButtons = {
},
reportStatus () {
this.$store.dispatch('openUserReportingModal', { userId: this.status.user.id, statusIds: [this.status.id] })
+ },
+ editStatus () {
+ this.$store.dispatch('fetchStatusSource', { id: this.status.id })
+ .then(data => this.$store.dispatch('openEditStatusModal', {
+ statusId: this.status.id,
+ subject: data.spoiler_text,
+ statusText: data.text,
+ statusIsSensitive: this.status.nsfw,
+ statusPoll: this.status.poll,
+ statusFiles: this.status.attachments,
+ visibility: this.status.visibility,
+ statusContentType: data.content_type
+ }))
}
},
computed: {
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index a3c3c767..8e90ee27 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -73,6 +73,17 @@
icon="bookmark"
/>{{ $t("status.unbookmark") }}
+
+
+ {{ $t('post_status.edit_remote_warning') }}
+
+ {{ $t('post_status.edit_unsupported_warning') }}
+
Date: Sat, 11 Jun 2022 23:51:13 -0600
Subject: Clarification on unsupported edit features warning
---
src/i18n/en.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/i18n/en.json b/src/i18n/en.json
index a303c0e8..b7a1dcbf 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -217,7 +217,7 @@
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
"edit_remote_warning": "Other remote instances may not support editing and unable to receive the latest version of your post.",
- "edit_unsupported_warning": "Pleroma currently does not support editing mentions or polls.",
+ "edit_unsupported_warning": "Pleroma does not support removing mentions or editing polls.",
"posting": "Posting",
"post": "Post",
"preview": "Preview",
--
cgit v1.2.3-70-g09d2
From 1b796691b0c396c1780e5520bf285e22923f3b6a Mon Sep 17 00:00:00 2001
From: Sean King
Date: Sun, 12 Jun 2022 10:16:56 -0600
Subject: Change message on unsupported edit features
---
src/i18n/en.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/i18n/en.json b/src/i18n/en.json
index b7a1dcbf..7b1bac79 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -217,7 +217,7 @@
"direct_warning_to_all": "This post will be visible to all the mentioned users.",
"direct_warning_to_first_only": "This post will only be visible to the mentioned users at the beginning of the message.",
"edit_remote_warning": "Other remote instances may not support editing and unable to receive the latest version of your post.",
- "edit_unsupported_warning": "Pleroma does not support removing mentions or editing polls.",
+ "edit_unsupported_warning": "Pleroma does not support editing mentions or polls.",
"posting": "Posting",
"post": "Post",
"preview": "Preview",
--
cgit v1.2.3-70-g09d2
From fa5d35523dd081b6948d38325374cac5707b7868 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Mon, 20 Jun 2022 22:52:08 -0600
Subject: Add ability to view status history for edited statuses
---
src/App.js | 2 +
src/App.vue | 1 +
src/components/extra_buttons/extra_buttons.js | 23 ++++++++-
src/components/extra_buttons/extra_buttons.vue | 11 ++++
.../status_history_modal/status_history_modal.js | 60 ++++++++++++++++++++++
.../status_history_modal/status_history_modal.vue | 46 +++++++++++++++++
src/i18n/en.json | 3 +-
src/main.js | 2 +
src/modules/statusHistory.js | 25 +++++++++
src/modules/statuses.js | 3 ++
src/services/api/api.service.js | 17 +++---
.../entity_normalizer/entity_normalizer.service.js | 6 ++-
12 files changed, 186 insertions(+), 13 deletions(-)
create mode 100644 src/components/status_history_modal/status_history_modal.js
create mode 100644 src/components/status_history_modal/status_history_modal.vue
create mode 100644 src/modules/statusHistory.js
(limited to 'src')
diff --git a/src/App.js b/src/App.js
index 6e0e34a8..af638a1c 100644
--- a/src/App.js
+++ b/src/App.js
@@ -13,6 +13,7 @@ import DesktopNav from './components/desktop_nav/desktop_nav.vue'
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
+import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
import { mapGetters } from 'vuex'
@@ -37,6 +38,7 @@ export default {
UserReportingModal,
PostStatusModal,
EditStatusModal,
+ StatusHistoryModal,
GlobalNoticeList
},
data: () => ({
diff --git a/src/App.vue b/src/App.vue
index 9484f993..1b513e08 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -53,6 +53,7 @@
+
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 8a703953..11fe3235 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -6,7 +6,8 @@ import {
faEyeSlash,
faThumbtack,
faShareAlt,
- faExternalLinkAlt
+ faExternalLinkAlt,
+ faHistory
} from '@fortawesome/free-solid-svg-icons'
import {
faBookmark as faBookmarkReg,
@@ -21,7 +22,8 @@ library.add(
faThumbtack,
faShareAlt,
faExternalLinkAlt,
- faFlag
+ faFlag,
+ faHistory
)
const ExtraButtons = {
@@ -84,6 +86,20 @@ const ExtraButtons = {
visibility: this.status.visibility,
statusContentType: data.content_type
}))
+ },
+ showStatusHistory () {
+ let originalStatus = {}
+ Object.assign(originalStatus, this.status)
+ delete originalStatus.attachments
+ delete originalStatus.created_at
+ delete originalStatus.emojis
+ delete originalStatus.text
+ delete originalStatus.raw_html
+ delete originalStatus.nsfw
+ delete originalStatus.poll
+ delete originalStatus.summary
+ delete originalStatus.summary_raw_html
+ this.$store.dispatch('openStatusHistoryModal', originalStatus)
}
},
computed: {
@@ -104,6 +120,9 @@ const ExtraButtons = {
},
statusLink () {
return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`
+ },
+ isEdited () {
+ return this.status.edited_at !== null
}
}
}
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 8e90ee27..877e1424 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -84,6 +84,17 @@
icon="pen"
/>{{ $t("status.edit") }}
+
{{ $t("status.edit") }}
:first-child {
+ margin-top: 0;
+ }
+
+ > :last-child {
+ margin-bottom: 0;
+ }
+ }
+
.media-upload-icon, .poll-icon, .emoji-icon {
font-size: 1.85em;
line-height: 1.1;
--
cgit v1.2.3-70-g09d2
From ed8bc6102290cb50d44c1c7aa5696aac5624d907 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Wed, 22 Jun 2022 16:05:27 -0400
Subject: Add last edited at indicator in status
---
src/components/status/status.js | 6 ++++++
src/components/status/status.scss | 3 ++-
src/components/status/status.vue | 24 ++++++++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/status/status.js b/src/components/status/status.js
index a925f30b..b7f20374 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -392,6 +392,12 @@ const Status = {
},
visibilityLocalized () {
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
+ },
+ isEdited () {
+ return this.status.edited_at !== null
+ },
+ editingAvailable () {
+ return this.$store.state.instance.editingAvailable
}
},
methods: {
diff --git a/src/components/status/status.scss b/src/components/status/status.scss
index b3ad3818..ada9841e 100644
--- a/src/components/status/status.scss
+++ b/src/components/status/status.scss
@@ -156,7 +156,8 @@
margin-right: 0.2em;
}
- & .heading-reply-row {
+ & .heading-reply-row,
+ & .heading-edited-row {
position: relative;
align-content: baseline;
font-size: 0.85em;
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 67ce999a..a9630a53 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -328,6 +328,30 @@
class="mentions-line"
/>
+
+
+
+
+
+
+
+
+
+
+
Date: Wed, 22 Jun 2022 16:05:44 -0400
Subject: Add English translation for last edited at indicator
---
src/i18n/en.json | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/i18n/en.json b/src/i18n/en.json
index f125c249..c4a044f5 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -748,6 +748,7 @@
"repeats": "Repeats",
"delete": "Delete status",
"edit": "Edit status",
+ "edited_at": "(last edited {time})",
"pin": "Pin on profile",
"unpin": "Unpin from profile",
"pinned": "Pinned",
--
cgit v1.2.3-70-g09d2
From acd53957e09a499b04c8f901e5829607f7363b57 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Wed, 22 Jun 2022 16:14:19 -0400
Subject: Do not show edited indicator in history items
---
src/components/status/status.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index a9630a53..00462f0a 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -329,7 +329,7 @@
/>
Date: Sun, 26 Jun 2022 13:25:36 -0600
Subject: Use watch to change localDescription
---
src/components/attachment/attachment.js | 3 +++
src/components/attachment/attachment.vue | 6 +++---
2 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index d62a4adc..5dc50475 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -129,6 +129,9 @@ const Attachment = {
...mapGetters(['mergedConfig'])
},
watch: {
+ 'attachment.description' (newVal) {
+ this.localDescription = newVal
+ },
localDescription (newVal) {
this.onEdit(newVal)
}
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 14f6a0ae..2a89886d 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -166,7 +166,7 @@
:icon="placeholderIconClass"
/>
- {{ edit ? localDescription : attachment.description }}
+ {{ localDescription }}
@@ -244,7 +244,7 @@
@@ -257,7 +257,7 @@
@keydown.enter.prevent=""
>
- {{ attachment.description }}
+ {{ localDescription }}
--
cgit v1.2.3-70-g09d2
From 6f4b57e84559871f8c59f968d5cf17f2971e74c3 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Sun, 26 Jun 2022 17:41:21 -0600
Subject: Use a better way to clone the original status
---
src/components/extra_buttons/extra_buttons.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 92eb63b0..5ddb7f0f 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -88,8 +88,7 @@ const ExtraButtons = {
}))
},
showStatusHistory () {
- let originalStatus = {}
- Object.assign(originalStatus, this.status)
+ let originalStatus = { ...this.status }
delete originalStatus.attachments
delete originalStatus.created_at
delete originalStatus.emojis
--
cgit v1.2.3-70-g09d2
From 29ff63d1b420d0c36fb16c72389fdccd1294205a Mon Sep 17 00:00:00 2001
From: Sean King
Date: Sun, 26 Jun 2022 18:10:30 -0600
Subject: Refactor to delete the properties for originalStatus in
showStatusHistory in a better way
---
src/components/extra_buttons/extra_buttons.js | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
(limited to 'src')
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 5ddb7f0f..ef040d26 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -88,16 +88,9 @@ const ExtraButtons = {
}))
},
showStatusHistory () {
- let originalStatus = { ...this.status }
- delete originalStatus.attachments
- delete originalStatus.created_at
- delete originalStatus.emojis
- delete originalStatus.text
- delete originalStatus.raw_html
- delete originalStatus.nsfw
- delete originalStatus.poll
- delete originalStatus.summary
- delete originalStatus.summary_raw_html
+ const originalStatus = { ...this.status }
+ const stripFieldsList = ['attachments', 'created_at', 'emojis', 'text', 'raw_html', 'nsfw', 'poll', 'summary', 'summary_raw_html']
+ stripFieldsList.forEach(p => delete originalStatus[p])
this.$store.dispatch('openStatusHistoryModal', originalStatus)
}
},
--
cgit v1.2.3-70-g09d2
From 75216c5feb32b32e24952663ffa4233410585785 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Sun, 10 Jul 2022 21:07:47 -0600
Subject: Remove guard for raw_html
---
src/components/status_body/status_body.js | 7 -------
1 file changed, 7 deletions(-)
(limited to 'src')
diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js
index 0a3dcf79..b8f6f9a0 100644
--- a/src/components/status_body/status_body.js
+++ b/src/components/status_body/status_body.js
@@ -125,13 +125,6 @@ const StatusContent = {
generateTagLink (tag) {
return `/tag/${tag}`
}
- },
- watch: {
- 'status.raw_html' (newVal, oldVal) {
- if (newVal !== oldVal) {
- this.parseReadyDone = false
- }
- }
}
}
--
cgit v1.2.3-70-g09d2
From 232cc72df8352db15ac3e6b11c1f9c5908069771 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Mon, 1 Aug 2022 18:45:52 -0600
Subject: Fix lint errors and warnings
---
src/components/edit_status_modal/edit_status_modal.vue | 6 +++---
src/components/status/status.vue | 12 +++++-------
src/components/status_history_modal/status_history_modal.vue | 4 ++--
src/services/api/api.service.js | 6 +++---
src/services/entity_normalizer/entity_normalizer.service.js | 2 +-
5 files changed, 14 insertions(+), 16 deletions(-)
(limited to 'src')
diff --git a/src/components/edit_status_modal/edit_status_modal.vue b/src/components/edit_status_modal/edit_status_modal.vue
index 00dde7de..1dbacaab 100644
--- a/src/components/edit_status_modal/edit_status_modal.vue
+++ b/src/components/edit_status_modal/edit_status_modal.vue
@@ -11,10 +11,10 @@
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index a13e5ab0..5ddb94b4 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -340,13 +340,11 @@
keypath="time.in_past"
tag="span"
>
-
-
-
+
diff --git a/src/components/status_history_modal/status_history_modal.vue b/src/components/status_history_modal/status_history_modal.vue
index d6680df2..990be35b 100644
--- a/src/components/status_history_modal/status_history_modal.vue
+++ b/src/components/status_history_modal/status_history_modal.vue
@@ -17,9 +17,9 @@
v-for="status in history"
:key="status.id"
:statusoid="status"
- :isPreview="true"
+ :is-preview="true"
class="conversation-status status-fadein panel-body"
- />
+ />
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 41c14596..381dd112 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -417,7 +417,7 @@ const fetchStatus = ({ id, credentials }) => {
}
const fetchStatusSource = ({ id, credentials }) => {
- let url = MASTODON_STATUS_SOURCE_URL(id)
+ const url = MASTODON_STATUS_SOURCE_URL(id)
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => {
if (data.ok) {
@@ -430,7 +430,7 @@ const fetchStatusSource = ({ id, credentials }) => {
}
const fetchStatusHistory = ({ status, credentials }) => {
- let url = MASTODON_STATUS_HISTORY_URL(status.id)
+ const url = MASTODON_STATUS_HISTORY_URL(status.id)
return promisedRequest({ url, credentials })
.then((data) => {
data.reverse()
@@ -767,7 +767,7 @@ const editStatus = ({
})
}
- let putHeaders = authHeaders(credentials)
+ const putHeaders = authHeaders(credentials)
return fetch(MASTODON_STATUS_URL(id), {
body: form,
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index c00e9796..c1b2ffac 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -378,7 +378,7 @@ export const parseStatus = (data) => {
output.favoritedBy = []
output.rebloggedBy = []
- if (data.hasOwnProperty('originalStatus')) {
+ if (Object.prototype.hasOwnProperty.call(data, 'originalStatus')) {
Object.assign(output, data.originalStatus)
}
--
cgit v1.2.3-70-g09d2
From b70d50407cef26926635b1b47131c01e597fcfc6 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Mon, 1 Aug 2022 21:25:08 -0600
Subject: Refresh the relative time object for a Timeago component if the time
changes
---
src/components/timeago/timeago.vue | 7 +++++++
1 file changed, 7 insertions(+)
(limited to 'src')
diff --git a/src/components/timeago/timeago.vue b/src/components/timeago/timeago.vue
index 2b487dfd..fce9605b 100644
--- a/src/components/timeago/timeago.vue
+++ b/src/components/timeago/timeago.vue
@@ -34,6 +34,13 @@ export default {
unmounted () {
clearTimeout(this.interval)
},
+ watch: {
+ time (newVal, oldVal) {
+ if (oldVal !== newVal) {
+ this.refreshRelativeTimeObject()
+ }
+ }
+ },
methods: {
refreshRelativeTimeObject () {
const nowThreshold = typeof this.nowThreshold === 'number' ? this.nowThreshold : 1
--
cgit v1.2.3-70-g09d2
From 04e62df377fdd2ea563f58dcd23ea8048fc1c140 Mon Sep 17 00:00:00 2001
From: Sean King
Date: Tue, 2 Aug 2022 23:19:25 -0600
Subject: Allow for template inside Timeago component that shows unless the
time string is 'just now'
---
src/components/status/status.vue | 16 ++++++----------
src/components/timeago/timeago.vue | 26 ++++++++++++++++++--------
2 files changed, 24 insertions(+), 18 deletions(-)
(limited to 'src')
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 5ddb94b4..8036ddf4 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -336,16 +336,12 @@
tag="span"
>
-
-
-
+
diff --git a/src/components/timeago/timeago.vue b/src/components/timeago/timeago.vue
index fce9605b..b5f49515 100644
--- a/src/components/timeago/timeago.vue
+++ b/src/components/timeago/timeago.vue
@@ -3,7 +3,7 @@
:datetime="time"
:title="localeDateString"
>
- {{ $tc(relativeTime.key, relativeTime.num, [relativeTime.num]) }}
+ {{ relativeTimeString }}
@@ -13,7 +13,7 @@ import localeService from 'src/services/locale/locale.service.js'
export default {
name: 'Timeago',
- props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold'],
+ props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold', 'templateKey'],
data () {
return {
relativeTime: { key: 'time.now', num: 0 },
@@ -26,21 +26,31 @@ export default {
return typeof this.time === 'string'
? new Date(Date.parse(this.time)).toLocaleString(browserLocale)
: this.time.toLocaleString(browserLocale)
+ },
+ relativeTimeString () {
+ const timeString = this.$i18n.tc(this.relativeTime.key, this.relativeTime.num, [this.relativeTime.num])
+
+ if (typeof this.templateKey === 'string' && this.relativeTime.key !== 'time.now') {
+ return this.$i18n.t(this.templateKey, [timeString])
+ }
+
+ return timeString
}
},
- created () {
- this.refreshRelativeTimeObject()
- },
- unmounted () {
- clearTimeout(this.interval)
- },
watch: {
time (newVal, oldVal) {
if (oldVal !== newVal) {
+ clearTimeout(this.interval)
this.refreshRelativeTimeObject()
}
}
},
+ created () {
+ this.refreshRelativeTimeObject()
+ },
+ unmounted () {
+ clearTimeout(this.interval)
+ },
methods: {
refreshRelativeTimeObject () {
const nowThreshold = typeof this.nowThreshold === 'number' ? this.nowThreshold : 1
--
cgit v1.2.3-70-g09d2
From 420f29b6a460ead0a5b4d9ff61e3d3ca097bd798 Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Tue, 23 Aug 2022 02:01:56 +0300
Subject: add a mask to load shape to flow text around quicker
---
src/assets/pleromatan_apology_fox_mask.png | Bin 0 -> 2827 bytes
src/assets/pleromatan_apology_mask.png | Bin 0 -> 2366 bytes
.../update_notification/update_notification.js | 5 ++++-
3 files changed, 4 insertions(+), 1 deletion(-)
create mode 100644 src/assets/pleromatan_apology_fox_mask.png
create mode 100644 src/assets/pleromatan_apology_mask.png
(limited to 'src')
diff --git a/src/assets/pleromatan_apology_fox_mask.png b/src/assets/pleromatan_apology_fox_mask.png
new file mode 100644
index 00000000..4d1990d5
Binary files /dev/null and b/src/assets/pleromatan_apology_fox_mask.png differ
diff --git a/src/assets/pleromatan_apology_mask.png b/src/assets/pleromatan_apology_mask.png
new file mode 100644
index 00000000..18adafff
Binary files /dev/null and b/src/assets/pleromatan_apology_mask.png differ
diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js
index ba008d81..6cfe893c 100644
--- a/src/components/update_notification/update_notification.js
+++ b/src/components/update_notification/update_notification.js
@@ -2,6 +2,8 @@ import Modal from 'src/components/modal/modal.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import pleromaTan from 'src/assets/pleromatan_apology.png'
import pleromaTanFox from 'src/assets/pleromatan_apology_fox.png'
+import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png'
+import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png'
import {
faTimes
@@ -25,8 +27,9 @@ const UpdateNotification = {
},
computed: {
pleromaTanStyles () {
+ const mask = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask
return {
- 'shape-outside': 'url(' + this.pleromaTanVariant + ')'
+ 'shape-outside': 'url(' + mask + ')'
}
},
dynamicStyles () {
--
cgit v1.2.3-70-g09d2
From 6e1639cc1e0f15760fdb26786c28fca4c3fd8c17 Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Tue, 23 Aug 2022 02:06:54 +0300
Subject: fetch text height only after mask has been loaded
---
src/components/update_notification/update_notification.js | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js
index 6cfe893c..c389750d 100644
--- a/src/components/update_notification/update_notification.js
+++ b/src/components/update_notification/update_notification.js
@@ -60,9 +60,14 @@ const UpdateNotification = {
}
},
mounted () {
- setTimeout(() => {
- this.contentHeight = this.$refs.animatedText.scrollHeight
- }, 1000)
+ // Workaround to get the text height only after mask loaded. A bit hacky.
+ const newImg = new Image()
+ newImg.onload = () => {
+ setTimeout(() => {
+ this.contentHeight = this.$refs.animatedText.scrollHeight
+ }, 100)
+ }
+ newImg.src = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask
}
}
--
cgit v1.2.3-70-g09d2
From 8ecb67230c87754d43c4255c56c05566c8c53feb Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Wed, 31 Aug 2022 00:48:38 +0300
Subject: make custom router-link for nav-entry to un-nest the interactive
elements
---
src/components/nav_panel/nav_panel.vue | 7 --
src/components/navigation/navigation_entry.js | 4 +
src/components/navigation/navigation_entry.vue | 133 +++++++++++----------
.../optional_router_link/optional_router_link.vue | 22 ++++
4 files changed, 99 insertions(+), 67 deletions(-)
create mode 100644 src/components/optional_router_link/optional_router_link.vue
(limited to 'src')
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
index 2688bcf4..7373ca63 100644
--- a/src/components/nav_panel/nav_panel.vue
+++ b/src/components/nav_panel/nav_panel.vue
@@ -121,7 +121,6 @@
border-bottom: 1px solid;
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
- padding: 0;
}
> li {
@@ -150,12 +149,6 @@
font-size: 1.1em;
}
- .menu-item {
- .timelines-chevron {
- margin-right: 0;
- }
- }
-
.timelines-background {
padding: 0 0 0 0.6em;
background-color: $fallback--lightBg;
diff --git a/src/components/navigation/navigation_entry.js b/src/components/navigation/navigation_entry.js
index fe3402fc..81cc936a 100644
--- a/src/components/navigation/navigation_entry.js
+++ b/src/components/navigation/navigation_entry.js
@@ -1,5 +1,6 @@
import { mapState } from 'vuex'
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
+import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faThumbtack } from '@fortawesome/free-solid-svg-icons'
@@ -7,6 +8,9 @@ library.add(faThumbtack)
const NavigationEntry = {
props: ['item', 'showPin'],
+ components: {
+ OptionalRouterLink
+ },
methods: {
isPinned (value) {
return this.pinnedItems.has(value)
diff --git a/src/components/navigation/navigation_entry.vue b/src/components/navigation/navigation_entry.vue
index 824c00a2..b984b234 100644
--- a/src/components/navigation/navigation_entry.vue
+++ b/src/components/navigation/navigation_entry.vue
@@ -1,26 +1,37 @@
-
-
-
+
+
@@ -55,7 +66,21 @@
@import '../../_variables.scss';
.NavigationEntry {
- .label {
+ display: flex;
+ box-sizing: border-box;
+ align-items: baseline;
+ height: 3.5em;
+ line-height: 3.5em;
+ padding: 0 1em;
+ width: 100%;
+ color: $fallback--link;
+ color: var(--link, $fallback--link);
+
+ .timelines-chevron {
+ margin-right: 0;
+ }
+
+ .main-link {
flex: 1;
}
@@ -72,48 +97,36 @@
}
}
- .menu-item {
- display: flex;
- box-sizing: border-box;
- align-items: baseline;
- height: 3.5em;
- line-height: 3.5em;
- padding: 0 1em;
- width: 100%;
+ &:hover {
+ background-color: $fallback--lightBg;
+ background-color: var(--selectedMenu, $fallback--lightBg);
color: $fallback--link;
- color: var(--link, $fallback--link);
-
- &:hover {
- background-color: $fallback--lightBg;
- background-color: var(--selectedMenu, $fallback--lightBg);
- color: $fallback--link;
- color: var(--selectedMenuText, $fallback--link);
- --faint: var(--selectedMenuFaintText, $fallback--faint);
- --faintLink: var(--selectedMenuFaintLink, $fallback--faint);
- --lightText: var(--selectedMenuLightText, $fallback--lightText);
+ color: var(--selectedMenuText, $fallback--link);
+ --faint: var(--selectedMenuFaintText, $fallback--faint);
+ --faintLink: var(--selectedMenuFaintLink, $fallback--faint);
+ --lightText: var(--selectedMenuLightText, $fallback--lightText);
- .menu-icon {
- --icon: var(--text, $fallback--icon);
- }
+ .menu-icon {
+ --icon: var(--text, $fallback--icon);
}
+ }
- &.router-link-active {
- font-weight: bolder;
- background-color: $fallback--lightBg;
- background-color: var(--selectedMenu, $fallback--lightBg);
- color: $fallback--text;
- color: var(--selectedMenuText, $fallback--text);
- --faint: var(--selectedMenuFaintText, $fallback--faint);
- --faintLink: var(--selectedMenuFaintLink, $fallback--faint);
- --lightText: var(--selectedMenuLightText, $fallback--lightText);
+ &.-active {
+ font-weight: bolder;
+ background-color: $fallback--lightBg;
+ background-color: var(--selectedMenu, $fallback--lightBg);
+ color: $fallback--text;
+ color: var(--selectedMenuText, $fallback--text);
+ --faint: var(--selectedMenuFaintText, $fallback--faint);
+ --faintLink: var(--selectedMenuFaintLink, $fallback--faint);
+ --lightText: var(--selectedMenuLightText, $fallback--lightText);
- .menu-icon {
- --icon: var(--text, $fallback--icon);
- }
+ .menu-icon {
+ --icon: var(--text, $fallback--icon);
+ }
- &:hover {
- text-decoration: underline;
- }
+ &:hover {
+ text-decoration: underline;
}
}
}
diff --git a/src/components/optional_router_link/optional_router_link.vue b/src/components/optional_router_link/optional_router_link.vue
new file mode 100644
index 00000000..4eef0d6a
--- /dev/null
+++ b/src/components/optional_router_link/optional_router_link.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
--
cgit v1.2.3-70-g09d2
From 98f97ff9a9806b2cb16f9b9f15df531be0f98919 Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Wed, 31 Aug 2022 00:57:02 +0300
Subject: lint
---
src/components/optional_router_link/optional_router_link.vue | 1 +
1 file changed, 1 insertion(+)
(limited to 'src')
diff --git a/src/components/optional_router_link/optional_router_link.vue b/src/components/optional_router_link/optional_router_link.vue
index 4eef0d6a..a9877dd5 100644
--- a/src/components/optional_router_link/optional_router_link.vue
+++ b/src/components/optional_router_link/optional_router_link.vue
@@ -1,4 +1,5 @@
+
Date: Wed, 31 Aug 2022 00:58:03 +0300
Subject: lint
---
src/components/navigation/navigation_entry.vue | 6 +++---
src/components/optional_router_link/optional_router_link.vue | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/components/navigation/navigation_entry.vue b/src/components/navigation/navigation_entry.vue
index b984b234..f4d53836 100644
--- a/src/components/navigation/navigation_entry.vue
+++ b/src/components/navigation/navigation_entry.vue
@@ -1,8 +1,8 @@
@@ -40,6 +45,12 @@
line-height: 1.5em;
}
+ &-button {
+ margin-top: 0.5em;
+ padding: 0 1.5em;
+ margin-left: 1em;
+ }
+
&-follow-button {
margin-top: 0.5em;
margin-left: auto;
diff --git a/src/components/remove_follower_button/remove_follower_button.js b/src/components/remove_follower_button/remove_follower_button.js
new file mode 100644
index 00000000..e1a7531b
--- /dev/null
+++ b/src/components/remove_follower_button/remove_follower_button.js
@@ -0,0 +1,25 @@
+export default {
+ props: ['relationship'],
+ data () {
+ return {
+ inProgress: false
+ }
+ },
+ computed: {
+ label () {
+ if (this.inProgress) {
+ return this.$t('user_card.follow_progress')
+ } else {
+ return this.$t('user_card.remove_follower')
+ }
+ }
+ },
+ methods: {
+ onClick () {
+ this.inProgress = true
+ this.$store.dispatch('removeUserFromFollowers', this.relationship.id).then(() => {
+ this.inProgress = false
+ })
+ }
+ }
+}
diff --git a/src/components/remove_follower_button/remove_follower_button.vue b/src/components/remove_follower_button/remove_follower_button.vue
new file mode 100644
index 00000000..a3a4c242
--- /dev/null
+++ b/src/components/remove_follower_button/remove_follower_button.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/src/i18n/en.json b/src/i18n/en.json
index ae63f6e6..22ec42a9 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -878,7 +878,7 @@
"muted": "Muted",
"per_day": "per day",
"remote_follow": "Remote follow",
- "remove_this_follower": "Remove this follower",
+ "remove_follower": "Remove follower",
"report": "Report",
"statuses": "Statuses",
"subscribe": "Subscribe",
--
cgit v1.2.3-70-g09d2
From 69b3102fb2396edb63abe98b4a69ebe311e22a70 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sat, 14 Aug 2021 21:10:24 -0400
Subject: Group custom emojis by pack in emoji picker
---
src/components/emoji_picker/emoji_picker.js | 29 ++++++++++++++++++++-------
src/components/emoji_picker/emoji_picker.scss | 13 ++++++++++++
src/components/emoji_picker/emoji_picker.vue | 10 +++++++++
3 files changed, 45 insertions(+), 7 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index f6920208..9e398176 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -183,17 +183,32 @@ const EmojiPicker = {
customEmojiBuffer () {
return this.filteredEmoji.slice(0, this.customEmojiBufferSlice)
},
+ groupedCustomEmojis () {
+ const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
+ return this.customEmojiBuffer.reduce((res, emoji) => {
+ const pack = packOf(emoji)
+ if (!res[pack]) {
+ res[pack] = {
+ id: `custom-${pack}`,
+ text: pack,
+ /// FIXME
+ // icon: 'smile-beam',
+ image: emoji.imageUrl,
+ emojis: []
+ }
+ }
+ res[pack].emojis.push(emoji)
+ return res
+ }, {})
+ },
emojis () {
const standardEmojis = this.$store.state.instance.emoji || []
- const customEmojis = this.customEmojiBuffer
+ // const customEmojis = this.customEmojiBuffer
return [
- {
- id: 'custom',
- text: this.$t('emoji.custom'),
- icon: 'smile-beam',
- emojis: customEmojis
- },
+ ...Object
+ .keys(this.groupedCustomEmojis)
+ .map(k => this.groupedCustomEmojis[k]),
{
id: 'standard',
text: this.$t('emoji.unicode'),
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index a2f17c51..ccb12a2a 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -19,6 +19,19 @@
--lightText: var(--popoverLightText, $fallback--lightText);
--icon: var(--popoverIcon, $fallback--icon);
+ &-header-image {
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ width: 30px;
+ height: 24px;
+ img {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ }
+ }
+
.keep-open,
.too-many-emoji {
padding: 7px;
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index a7269120..16549c08 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -13,7 +13,17 @@
:title="group.text"
@click.prevent="highlight(group.id)"
>
+
--
cgit v1.2.3-70-g09d2
From ff2242e85dc89aa7479000cf469ca2bce5d60157 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sat, 14 Aug 2021 21:23:45 -0400
Subject: Fix load more emoji action
---
src/components/emoji_picker/emoji_picker.js | 5 ++++-
src/modules/instance.js | 12 +++++++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 9e398176..7d5a3d8f 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -98,7 +98,7 @@ const EmojiPicker = {
}
},
triggerLoadMore (target) {
- const ref = this.$refs['group-end-custom']
+ const ref = this.$refs[`group-end-${this.lastNonUnicodeGroupId}`][0]
if (!ref) return
const bottom = ref.offsetTop + ref.offsetHeight
@@ -217,6 +217,9 @@ const EmojiPicker = {
}
]
},
+ lastNonUnicodeGroupId () {
+ return this.emojis[this.emojis.length - 2].id
+ },
emojisView () {
return this.emojis.filter(value => value.emojis.length > 0)
},
diff --git a/src/modules/instance.js b/src/modules/instance.js
index bfce6f38..23f534c3 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -164,6 +164,16 @@ const instance = {
if (res.ok) {
const result = await res.json()
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
+ const caseInsensitiveStrCmp = (a, b) => {
+ const la = a.toLowerCase()
+ const lb = b.toLowerCase()
+ return la > lb ? 1 : (la < lb ? -1 : 0)
+ }
+ const byPackThenByName = (a, b) => {
+ const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
+ return caseInsensitiveStrCmp(packOf(a), packOf(b)) || caseInsensitiveStrCmp(a.displayText, b.displayText)
+ }
+
const emoji = Object.entries(values).map(([key, value]) => {
const imageUrl = value.image_url
return {
@@ -174,7 +184,7 @@ const instance = {
}
// Technically could use tags but those are kinda useless right now,
// should have been "pack" field, that would be more useful
- }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1)
+ }).sort(byPackThenByName)
commit('setInstanceOption', { name: 'customEmoji', value: emoji })
} else {
throw (res)
--
cgit v1.2.3-70-g09d2
From 992d57ef69540f4c63939fbc5abed9b1ea28ed2f Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sat, 14 Aug 2021 21:50:58 -0400
Subject: Display all emoji groups on emoji picker header
---
src/components/emoji_picker/emoji_picker.js | 28 +++++++++++++++++++++++++--
src/components/emoji_picker/emoji_picker.scss | 6 +++++-
src/components/emoji_picker/emoji_picker.vue | 4 ++--
3 files changed, 33 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 7d5a3d8f..d04649dc 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -38,6 +38,8 @@ const filterByKeyword = (list, keyword = '') => {
return orderedEmojiList.flat()
}
+const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
+
const EmojiPicker = {
props: {
enableStickerPicker: {
@@ -174,9 +176,12 @@ const EmojiPicker = {
}
return 0
},
+ allEmojis () {
+ return this.$store.state.instance.customEmoji || []
+ },
filteredEmoji () {
return filterByKeyword(
- this.$store.state.instance.customEmoji || [],
+ this.allEmojis,
trim(this.keyword)
)
},
@@ -184,7 +189,6 @@ const EmojiPicker = {
return this.filteredEmoji.slice(0, this.customEmojiBufferSlice)
},
groupedCustomEmojis () {
- const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
return this.customEmojiBuffer.reduce((res, emoji) => {
const pack = packOf(emoji)
if (!res[pack]) {
@@ -201,6 +205,26 @@ const EmojiPicker = {
return res
}, {})
},
+ allEmojiGroups () {
+ return this.allEmojis
+ .reduce((res, emoji) => {
+ const packName = packOf(emoji)
+ const packId = `custom-${packName}`
+ if (res.filter(k => k.id === packId).length === 0) {
+ res.push({
+ id: packId,
+ text: packName,
+ image: emoji.imageUrl
+ })
+ }
+ return res
+ }, [])
+ .concat({
+ id: 'standard',
+ text: this.$t('emoji.unicode'),
+ icon: 'box-open'
+ })
+ },
emojis () {
const standardEmojis = this.$store.state.instance.emoji || []
// const customEmojis = this.customEmojiBuffer
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index ccb12a2a..0bd4363c 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -52,6 +52,7 @@
display: flex;
height: 32px;
padding: 10px 7px 5px;
+ overflow-x: auto;
}
.content {
@@ -63,6 +64,9 @@
.emoji-tabs {
flex-grow: 1;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
}
.emoji-groups {
@@ -70,6 +74,7 @@
}
.additional-tabs {
+ display: block;
border-left: 1px solid;
border-left-color: $fallback--icon;
border-left-color: var(--icon, $fallback--icon);
@@ -79,7 +84,6 @@
.additional-tabs,
.emoji-tabs {
- display: block;
min-width: 0;
flex-basis: auto;
flex-shrink: 1;
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 16549c08..fe60cb5e 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -3,12 +3,12 @@
Date: Sat, 14 Aug 2021 23:37:00 -0400
Subject: Load visible emoji groups when scrolling
---
src/components/emoji_picker/emoji_picker.js | 101 +++++++++++++++++++--------
src/components/emoji_picker/emoji_picker.vue | 4 +-
2 files changed, 75 insertions(+), 30 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index d04649dc..cab952f8 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -57,7 +57,8 @@ const EmojiPicker = {
keepOpen: false,
customEmojiBufferSlice: LOAD_EMOJI_BY,
customEmojiTimeout: null,
- customEmojiLoadAllConfirmed: false
+ customEmojiLoadAllConfirmed: false,
+ groupLoadedCount: {}
}
},
components: {
@@ -79,7 +80,9 @@ const EmojiPicker = {
const target = (e && e.target) || this.$refs['emoji-groups']
this.updateScrolledClass(target)
this.scrolledGroup(target)
- this.triggerLoadMore(target)
+ this.$nextTick(() => {
+ this.triggerLoadMore(target)
+ })
},
highlight (key) {
const ref = this.$refs['group-' + key]
@@ -88,6 +91,7 @@ const EmojiPicker = {
this.activeGroup = key
this.$nextTick(() => {
this.$refs['emoji-groups'].scrollTop = top + 1
+ this.loadEmoji(key)
})
},
updateScrolledClass (target) {
@@ -100,28 +104,40 @@ const EmojiPicker = {
}
},
triggerLoadMore (target) {
- const ref = this.$refs[`group-end-${this.lastNonUnicodeGroupId}`][0]
- if (!ref) return
- const bottom = ref.offsetTop + ref.offsetHeight
+ Object.keys(this.allCustomGroups)
+ .map(groupId => {
+ const ref = this.$refs[`group-end-${groupId}`][0]
+ if (!ref) return undefined
- const scrollerBottom = target.scrollTop + target.clientHeight
- const scrollerTop = target.scrollTop
- const scrollerMax = target.scrollHeight
+ const bottom = ref.offsetTop + ref.offsetHeight
- // Loads more emoji when they come into view
- const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN
- // Always load when at the very top in case there's no scroll space yet
- const atTop = scrollerTop < 5
- // Don't load when looking at unicode category or at the very bottom
- const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax
- if (!bottomAboveViewport && (approachingBottom || atTop)) {
- this.loadEmoji()
- }
+ const group = this.$refs[`group-${groupId}`][0]
+ const top = group.offsetTop
+
+ const scrollerBottom = target.scrollTop + target.clientHeight
+ const scrollerTop = target.scrollTop
+ const scrollerMax = target.scrollHeight
+
+ // Loads more emoji when they come into view
+ const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN
+ // Always load when at the very top in case there's no scroll space yet
+ const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom
+ // Don't load when looking at unicode category or at the very bottom
+ const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax
+ if (!bottomAboveViewport && (approachingBottom || atTop)) {
+ return groupId
+ }
+ return undefined
+ })
+ .filter(k => k)
+ .map(k => {
+ this.loadEmoji(k)
+ })
},
scrolledGroup (target) {
const top = target.scrollTop + 5
this.$nextTick(() => {
- this.emojisView.forEach(group => {
+ this.allEmojiGroups.forEach(group => {
const ref = this.$refs['group-' + group.id]
if (ref.offsetTop <= top) {
this.activeGroup = group.id
@@ -129,14 +145,21 @@ const EmojiPicker = {
})
})
},
- loadEmoji () {
- const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length
+ loadEmoji (loadGroup) {
+ if (!this.allCustomGroups[loadGroup]) {
+ return
+ }
+
+ const allLoaded = this.loadedCount[loadGroup] >= this.allCustomGroups[loadGroup].emojis.length
if (allLoaded) {
return
}
- this.customEmojiBufferSlice += LOAD_EMOJI_BY
+ this.groupLoadedCount = {
+ ...this.groupLoadedCount,
+ [loadGroup]: this.loadedCount[loadGroup] + LOAD_EMOJI_BY
+ }
},
startEmojiLoad (forceUpdate = false) {
if (!forceUpdate) {
@@ -157,6 +180,9 @@ const EmojiPicker = {
},
setShowStickers (value) {
this.showingStickers = value
+ },
+ limitedEmojis (list, groupId) {
+ return list.slice(0, this.loadedCount[groupId])
}
},
watch: {
@@ -205,24 +231,36 @@ const EmojiPicker = {
return res
}, {})
},
- allEmojiGroups () {
- return this.allEmojis
+ allCustomGroups () {
+ return this.filteredEmoji
.reduce((res, emoji) => {
const packName = packOf(emoji)
const packId = `custom-${packName}`
- if (res.filter(k => k.id === packId).length === 0) {
- res.push({
+ if (!res[packId]) {
+ res[packId] = ({
id: packId,
text: packName,
- image: emoji.imageUrl
+ image: emoji.imageUrl,
+ emojis: []
})
}
+ res[packId].emojis.push(emoji)
return res
- }, [])
+ }, {})
+ },
+ sensibleInitialAmountForAGroup () {
+ const groupCount = Object.keys(this.allCustomGroups).length
+ return Math.max(Math.floor(LOAD_EMOJI_BY / Math.max(groupCount, 1)), 1)
+ },
+ allEmojiGroups () {
+ const standardEmojis = this.$store.state.instance.emoji || []
+ return Object.entries(this.allCustomGroups)
+ .map(([_, v]) => v)
.concat({
id: 'standard',
text: this.$t('emoji.unicode'),
- icon: 'box-open'
+ icon: 'box-open',
+ emojis: filterByKeyword(standardEmojis, this.keyword)
})
},
emojis () {
@@ -241,6 +279,13 @@ const EmojiPicker = {
}
]
},
+ loadedCount () {
+ return Object.keys(this.allCustomGroups)
+ .reduce((res, groupId) => {
+ res[groupId] = this.groupLoadedCount[groupId] || this.sensibleInitialAmountForAGroup
+ return res
+ }, {})
+ },
lastNonUnicodeGroupId () {
return this.emojis[this.emojis.length - 2].id
},
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index fe60cb5e..277d5bf6 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -67,7 +67,7 @@
@scroll="onScroll"
>
@@ -78,7 +78,7 @@
{{ group.text }}
Date: Sun, 15 Aug 2021 00:03:31 -0400
Subject: Load emoji properly on first showing
---
src/components/emoji_picker/emoji_picker.js | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index cab952f8..322bb8ba 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -58,7 +58,8 @@ const EmojiPicker = {
customEmojiBufferSlice: LOAD_EMOJI_BY,
customEmojiTimeout: null,
customEmojiLoadAllConfirmed: false,
- groupLoadedCount: {}
+ groupLoadedCount: {},
+ firstLoaded: false
}
},
components: {
@@ -167,6 +168,13 @@ const EmojiPicker = {
}
this.$nextTick(() => {
this.$refs['emoji-groups'].scrollTop = 0
+ this.$nextTick(() => {
+ if (this.firstLoaded) {
+ return
+ }
+ this.triggerLoadMore(this.$refs['emoji-groups'])
+ this.firstLoaded = true
+ })
})
const bufferSize = this.customEmojiBuffer.length
const bufferPrefilledAll = bufferSize === this.filteredEmoji.length
--
cgit v1.2.3-70-g09d2
From 123913f34ffd91917a9ed4dd1c9d406fb547ef87 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sun, 15 Aug 2021 00:43:35 -0400
Subject: Optimise emoji picker loading process
---
src/components/emoji_picker/emoji_picker.js | 83 +++++-----------------------
src/components/emoji_picker/emoji_picker.vue | 4 +-
src/modules/instance.js | 18 ++++++
3 files changed, 34 insertions(+), 71 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 322bb8ba..67c6d0cc 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -106,6 +106,7 @@ const EmojiPicker = {
},
triggerLoadMore (target) {
Object.keys(this.allCustomGroups)
+ .filter(id => this.filteredEmojiGroups.filter(group => group.id === id).length > 0)
.map(groupId => {
const ref = this.$refs[`group-end-${groupId}`][0]
if (!ref) return undefined
@@ -123,9 +124,10 @@ const EmojiPicker = {
const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN
// Always load when at the very top in case there's no scroll space yet
const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom
+ const unscrollable = top - bottom < target.clientHeight
// Don't load when looking at unicode category or at the very bottom
const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax
- if (!bottomAboveViewport && (approachingBottom || atTop)) {
+ if (!bottomAboveViewport && (approachingBottom || atTop || unscrollable)) {
return groupId
}
return undefined
@@ -176,12 +178,6 @@ const EmojiPicker = {
this.firstLoaded = true
})
})
- const bufferSize = this.customEmojiBuffer.length
- const bufferPrefilledAll = bufferSize === this.filteredEmoji.length
- if (bufferPrefilledAll && !forceUpdate) {
- return
- }
- this.customEmojiBufferSlice = LOAD_EMOJI_BY
},
toggleStickers () {
this.showingStickers = !this.showingStickers
@@ -191,6 +187,9 @@ const EmojiPicker = {
},
limitedEmojis (list, groupId) {
return list.slice(0, this.loadedCount[groupId])
+ },
+ filterByKeyword (list, keyword) {
+ return filterByKeyword(list, keyword)
}
},
watch: {
@@ -210,51 +209,8 @@ const EmojiPicker = {
}
return 0
},
- allEmojis () {
- return this.$store.state.instance.customEmoji || []
- },
- filteredEmoji () {
- return filterByKeyword(
- this.allEmojis,
- trim(this.keyword)
- )
- },
- customEmojiBuffer () {
- return this.filteredEmoji.slice(0, this.customEmojiBufferSlice)
- },
- groupedCustomEmojis () {
- return this.customEmojiBuffer.reduce((res, emoji) => {
- const pack = packOf(emoji)
- if (!res[pack]) {
- res[pack] = {
- id: `custom-${pack}`,
- text: pack,
- /// FIXME
- // icon: 'smile-beam',
- image: emoji.imageUrl,
- emojis: []
- }
- }
- res[pack].emojis.push(emoji)
- return res
- }, {})
- },
allCustomGroups () {
- return this.filteredEmoji
- .reduce((res, emoji) => {
- const packName = packOf(emoji)
- const packId = `custom-${packName}`
- if (!res[packId]) {
- res[packId] = ({
- id: packId,
- text: packName,
- image: emoji.imageUrl,
- emojis: []
- })
- }
- res[packId].emojis.push(emoji)
- return res
- }, {})
+ return this.$store.getters.groupedCustomEmojis
},
sensibleInitialAmountForAGroup () {
const groupCount = Object.keys(this.allCustomGroups).length
@@ -271,21 +227,13 @@ const EmojiPicker = {
emojis: filterByKeyword(standardEmojis, this.keyword)
})
},
- emojis () {
- const standardEmojis = this.$store.state.instance.emoji || []
- // const customEmojis = this.customEmojiBuffer
-
- return [
- ...Object
- .keys(this.groupedCustomEmojis)
- .map(k => this.groupedCustomEmojis[k]),
- {
- id: 'standard',
- text: this.$t('emoji.unicode'),
- icon: 'box-open',
- emojis: filterByKeyword(standardEmojis, trim(this.keyword))
- }
- ]
+ filteredEmojiGroups () {
+ return this.allEmojiGroups
+ .map(group => ({
+ ...group,
+ emojis: filterByKeyword(group.emojis, this.keyword)
+ }))
+ .filter(group => group.emojis.length > 0)
},
loadedCount () {
return Object.keys(this.allCustomGroups)
@@ -297,9 +245,6 @@ const EmojiPicker = {
lastNonUnicodeGroupId () {
return this.emojis[this.emojis.length - 2].id
},
- emojisView () {
- return this.emojis.filter(value => value.emojis.length > 0)
- },
stickerPickerEnabled () {
return (this.$store.state.instance.stickers || []).length !== 0
}
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 277d5bf6..7b2b7fc8 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -3,7 +3,7 @@
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 23f534c3..8aadce77 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -115,6 +115,24 @@ const instance = {
.map(key => [key, state[key]])
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
+ groupedCustomEmojis (state) {
+ return state.customEmoji
+ .reduce((res, emoji) => {
+ emoji.tags.forEach(packName => {
+ const packId = `custom-${packName}`
+ if (!res[packId]) {
+ res[packId] = ({
+ id: packId,
+ text: packName,
+ image: emoji.imageUrl,
+ emojis: []
+ })
+ }
+ res[packId].emojis.push(emoji)
+ })
+ return res
+ }, {})
+ },
instanceDomain (state) {
return new URL(state.server).hostname
}
--
cgit v1.2.3-70-g09d2
From 90f757cc6d9e1e29c2567979d3c27765f84cdc6c Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sun, 15 Aug 2021 00:53:57 -0400
Subject: Lint
---
src/components/emoji_picker/emoji_picker.js | 2 --
1 file changed, 2 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 67c6d0cc..8e11f83f 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -38,8 +38,6 @@ const filterByKeyword = (list, keyword = '') => {
return orderedEmojiList.flat()
}
-const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5)
-
const EmojiPicker = {
props: {
enableStickerPicker: {
--
cgit v1.2.3-70-g09d2
From c70cdbb873eb77bc1aaf7edb9defdda59bdba1e1 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Thu, 7 Oct 2021 23:23:58 -0400
Subject: Use lozad for lazy image loading
Ref: grouped-emoji-picker
---
package.json | 1 +
src/components/emoji_picker/emoji_picker.js | 6 +++++-
src/components/emoji_picker/emoji_picker.vue | 3 ++-
src/directives/lazy_image_container.js | 13 +++++++++++++
yarn.lock | 5 +++++
5 files changed, 26 insertions(+), 2 deletions(-)
create mode 100644 src/directives/lazy_image_container.js
(limited to 'src')
diff --git a/package.json b/package.json
index 50a6b55f..06fb4916 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"js-cookie": "3.0.1",
"localforage": "1.10.0",
"parse-link-header": "2.0.0",
+ "lozad": "^1.16.0",
"phoenix": "1.6.2",
"punycode.js": "2.1.0",
"qrcode": "1.5.0",
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 8e11f83f..82e5ad0b 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,5 +1,6 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
+import LazyImageContainer from '../../directives/lazy_image_container'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBoxOpen,
@@ -64,6 +65,9 @@ const EmojiPicker = {
StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')),
Checkbox
},
+ directives: {
+ LazyImageContainer
+ },
methods: {
onStickerUploaded (e) {
this.$emit('sticker-uploaded', e)
@@ -184,7 +188,7 @@ const EmojiPicker = {
this.showingStickers = value
},
limitedEmojis (list, groupId) {
- return list.slice(0, this.loadedCount[groupId])
+ return list // list.slice(0, this.loadedCount[groupId])
},
filterByKeyword (list, keyword) {
return filterByKeyword(list, keyword)
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 7b2b7fc8..0e6c7e41 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -62,6 +62,7 @@
{{ emoji.replacement }}
diff --git a/src/directives/lazy_image_container.js b/src/directives/lazy_image_container.js
new file mode 100644
index 00000000..44adc828
--- /dev/null
+++ b/src/directives/lazy_image_container.js
@@ -0,0 +1,13 @@
+
+import lozad from 'lozad'
+
+const LazyImageContainer = {
+ inserted (el) {
+ const images = el.querySelectorAll('img')
+ console.log(images.length)
+ el.$observer = lozad(images)
+ el.$observer.observe()
+ }
+}
+
+export default LazyImageContainer
diff --git a/yarn.lock b/yarn.lock
index 2fefe76f..041fc1dc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5733,6 +5733,11 @@ lower-case@^2.0.2:
dependencies:
tslib "^2.0.3"
+lozad@^1.16.0:
+ version "1.16.0"
+ resolved "https://registry.yarnpkg.com/lozad/-/lozad-1.16.0.tgz#86ce732c64c69926ccdebb81c8c90bb3735948b4"
+ integrity sha512-JBr9WjvEFeKoyim3svo/gsQPTkgG/mOHJmDctZ/+U9H3ymUuvEkqpn8bdQMFsvTMcyRJrdJkLv0bXqGm0sP72w==
+
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
--
cgit v1.2.3-70-g09d2
From 8777b6eadd7deadf010dc36bb90514f75fc0da16 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 01:02:16 -0400
Subject: Clean up legacy code in emoji picker
Ref: grouped-emoji-picker
---
src/components/emoji_input/emoji_input.js | 1 -
src/components/emoji_picker/emoji_picker.js | 130 ++++++---------------------
src/components/emoji_picker/emoji_picker.vue | 3 +-
src/directives/lazy_image_container.js | 13 ---
4 files changed, 28 insertions(+), 119 deletions(-)
delete mode 100644 src/directives/lazy_image_container.js
(limited to 'src')
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index b664d6b3..fb2096c9 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -207,7 +207,6 @@ const EmojiInput = {
},
triggerShowPicker () {
this.showPicker = true
- this.$refs.picker.startEmojiLoad()
this.$nextTick(() => {
this.scrollIntoView()
this.focusPickerInput()
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 82e5ad0b..b0162479 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,6 +1,6 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
-import LazyImageContainer from '../../directives/lazy_image_container'
+import lozad from 'lozad'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBoxOpen,
@@ -54,7 +54,6 @@ const EmojiPicker = {
showingStickers: false,
groupsScrolledClass: 'scrolled-top',
keepOpen: false,
- customEmojiBufferSlice: LOAD_EMOJI_BY,
customEmojiTimeout: null,
customEmojiLoadAllConfirmed: false,
groupLoadedCount: {},
@@ -65,9 +64,6 @@ const EmojiPicker = {
StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')),
Checkbox
},
- directives: {
- LazyImageContainer
- },
methods: {
onStickerUploaded (e) {
this.$emit('sticker-uploaded', e)
@@ -82,10 +78,6 @@ const EmojiPicker = {
onScroll (e) {
const target = (e && e.target) || this.$refs['emoji-groups']
this.updateScrolledClass(target)
- this.scrolledGroup(target)
- this.$nextTick(() => {
- this.triggerLoadMore(target)
- })
},
highlight (key) {
const ref = this.$refs['group-' + key]
@@ -94,7 +86,6 @@ const EmojiPicker = {
this.activeGroup = key
this.$nextTick(() => {
this.$refs['emoji-groups'].scrollTop = top + 1
- this.loadEmoji(key)
})
},
updateScrolledClass (target) {
@@ -106,101 +97,48 @@ const EmojiPicker = {
this.groupsScrolledClass = 'scrolled-middle'
}
},
- triggerLoadMore (target) {
- Object.keys(this.allCustomGroups)
- .filter(id => this.filteredEmojiGroups.filter(group => group.id === id).length > 0)
- .map(groupId => {
- const ref = this.$refs[`group-end-${groupId}`][0]
- if (!ref) return undefined
-
- const bottom = ref.offsetTop + ref.offsetHeight
-
- const group = this.$refs[`group-${groupId}`][0]
- const top = group.offsetTop
-
- const scrollerBottom = target.scrollTop + target.clientHeight
- const scrollerTop = target.scrollTop
- const scrollerMax = target.scrollHeight
-
- // Loads more emoji when they come into view
- const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN
- // Always load when at the very top in case there's no scroll space yet
- const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom
- const unscrollable = top - bottom < target.clientHeight
- // Don't load when looking at unicode category or at the very bottom
- const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax
- if (!bottomAboveViewport && (approachingBottom || atTop || unscrollable)) {
- return groupId
- }
- return undefined
- })
- .filter(k => k)
- .map(k => {
- this.loadEmoji(k)
- })
- },
- scrolledGroup (target) {
- const top = target.scrollTop + 5
- this.$nextTick(() => {
- this.allEmojiGroups.forEach(group => {
- const ref = this.$refs['group-' + group.id]
- if (ref.offsetTop <= top) {
- this.activeGroup = group.id
- }
- })
- })
- },
- loadEmoji (loadGroup) {
- if (!this.allCustomGroups[loadGroup]) {
- return
- }
-
- const allLoaded = this.loadedCount[loadGroup] >= this.allCustomGroups[loadGroup].emojis.length
-
- if (allLoaded) {
- return
- }
-
- this.groupLoadedCount = {
- ...this.groupLoadedCount,
- [loadGroup]: this.loadedCount[loadGroup] + LOAD_EMOJI_BY
- }
- },
- startEmojiLoad (forceUpdate = false) {
- if (!forceUpdate) {
- this.keyword = ''
- }
- this.$nextTick(() => {
- this.$refs['emoji-groups'].scrollTop = 0
- this.$nextTick(() => {
- if (this.firstLoaded) {
- return
- }
- this.triggerLoadMore(this.$refs['emoji-groups'])
- this.firstLoaded = true
- })
- })
- },
toggleStickers () {
this.showingStickers = !this.showingStickers
},
setShowStickers (value) {
this.showingStickers = value
},
- limitedEmojis (list, groupId) {
- return list // list.slice(0, this.loadedCount[groupId])
- },
filterByKeyword (list, keyword) {
return filterByKeyword(list, keyword)
+ },
+ initializeLazyLoad () {
+ this.destroyLazyLoad()
+ this.$lozad = lozad('img', {})
+ this.$lozad.observe()
+ },
+ destroyLazyLoad () {
+ if (this.$lozad) {
+ if (this.$lozad.observer) {
+ this.$lozad.observer.disconnect()
+ }
+ if (this.$lozad.mutationObserver) {
+ this.$lozad.mutationObserver.disconnect()
+ }
+ }
}
},
watch: {
keyword () {
this.customEmojiLoadAllConfirmed = false
this.onScroll()
- this.startEmojiLoad(true)
+ // Wait for the dom to change
+ this.$nextTick(() => this.initializeLazyLoad())
+ },
+ allCustomGroups () {
+ this.$nextTick(() => this.initializeLazyLoad())
}
},
+ mounted () {
+ this.initializeLazyLoad()
+ },
+ destroyed () {
+ this.destroyLazyLoad()
+ },
computed: {
activeGroupView () {
return this.showingStickers ? '' : this.activeGroup
@@ -214,10 +152,6 @@ const EmojiPicker = {
allCustomGroups () {
return this.$store.getters.groupedCustomEmojis
},
- sensibleInitialAmountForAGroup () {
- const groupCount = Object.keys(this.allCustomGroups).length
- return Math.max(Math.floor(LOAD_EMOJI_BY / Math.max(groupCount, 1)), 1)
- },
allEmojiGroups () {
const standardEmojis = this.$store.state.instance.emoji || []
return Object.entries(this.allCustomGroups)
@@ -237,16 +171,6 @@ const EmojiPicker = {
}))
.filter(group => group.emojis.length > 0)
},
- loadedCount () {
- return Object.keys(this.allCustomGroups)
- .reduce((res, groupId) => {
- res[groupId] = this.groupLoadedCount[groupId] || this.sensibleInitialAmountForAGroup
- return res
- }, {})
- },
- lastNonUnicodeGroupId () {
- return this.emojis[this.emojis.length - 2].id
- },
stickerPickerEnabled () {
return (this.$store.state.instance.stickers || []).length !== 0
}
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 0e6c7e41..0df33c24 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -62,7 +62,6 @@
Date: Fri, 8 Oct 2021 01:11:32 -0400
Subject: Fix scrol->highlight behaviour
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index b0162479..31a455fd 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -78,6 +78,18 @@ const EmojiPicker = {
onScroll (e) {
const target = (e && e.target) || this.$refs['emoji-groups']
this.updateScrolledClass(target)
+ this.scrolledGroup(target)
+ },
+ scrolledGroup (target) {
+ const top = target.scrollTop + 5
+ this.$nextTick(() => {
+ this.allEmojiGroups.forEach(group => {
+ const ref = this.$refs['group-' + group.id]
+ if (ref[0].offsetTop <= top) {
+ this.activeGroup = group.id
+ }
+ })
+ })
},
highlight (key) {
const ref = this.$refs['group-' + key]
@@ -134,6 +146,9 @@ const EmojiPicker = {
}
},
mounted () {
+ if (this.defaultGroup) {
+ this.highlight(this.defaultGroup)
+ }
this.initializeLazyLoad()
},
destroyed () {
@@ -152,6 +167,9 @@ const EmojiPicker = {
allCustomGroups () {
return this.$store.getters.groupedCustomEmojis
},
+ defaultGroup () {
+ return Object.keys(this.allCustomGroups)[0]
+ },
allEmojiGroups () {
const standardEmojis = this.$store.state.instance.emoji || []
return Object.entries(this.allCustomGroups)
--
cgit v1.2.3-70-g09d2
From f1d6e6afce6a0a6d709ae6ede5f14bdf3cf48e2b Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 01:20:35 -0400
Subject: Clean up unused variables
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.js | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 31a455fd..d60daab7 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -15,13 +15,6 @@ library.add(
faSmileBeam
)
-// At widest, approximately 20 emoji are visible in a row,
-// loading 3 rows, could be overkill for narrow picker
-const LOAD_EMOJI_BY = 60
-
-// When to start loading new batch emoji, in pixels
-const LOAD_EMOJI_MARGIN = 64
-
const filterByKeyword = (list, keyword = '') => {
if (keyword === '') return list
@@ -54,10 +47,7 @@ const EmojiPicker = {
showingStickers: false,
groupsScrolledClass: 'scrolled-top',
keepOpen: false,
- customEmojiTimeout: null,
- customEmojiLoadAllConfirmed: false,
- groupLoadedCount: {},
- firstLoaded: false
+ customEmojiTimeout: null
}
},
components: {
@@ -136,7 +126,6 @@ const EmojiPicker = {
},
watch: {
keyword () {
- this.customEmojiLoadAllConfirmed = false
this.onScroll()
// Wait for the dom to change
this.$nextTick(() => this.initializeLazyLoad())
--
cgit v1.2.3-70-g09d2
From 031a01be7920e4cf3bda6ed5e4f3e589f9821121 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 13:06:03 -0400
Subject: Remove useless class `disabled` in emoji picker
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.vue | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 0df33c24..fb2eef25 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -7,8 +7,7 @@
:key="group.id"
class="emoji-tabs-item"
:class="{
- active: activeGroupView === group.id,
- disabled: false
+ active: activeGroupView === group.id
}"
:title="group.text"
@click.prevent="highlight(group.id)"
--
cgit v1.2.3-70-g09d2
From 5ab51613b738bf089770c2ad6d0ae9354d49bcee Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 13:17:47 -0400
Subject: Use StillImage for emoji group header
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.js | 4 +++-
src/components/emoji_picker/emoji_picker.vue | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index d60daab7..5b90c31e 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,5 +1,6 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
+import StillImage from '../still-image/still-image.vue'
import lozad from 'lozad'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -52,7 +53,8 @@ const EmojiPicker = {
},
components: {
StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')),
- Checkbox
+ Checkbox,
+ StillImage
},
methods: {
onStickerUploaded (e) {
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index fb2eef25..ed196066 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -16,10 +16,10 @@
v-if="group.image"
class="emoji-picker-header-image"
>
-
+ />
Date: Fri, 8 Oct 2021 14:10:17 -0400
Subject: Fix vertical scrollbar of emoji picker header
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.scss | 29 ++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index 0bd4363c..e315d2d7 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -1,5 +1,10 @@
@import '../../_variables.scss';
+$emoji-picker-header-height: 36px;
+$emoji-picker-header-picture-width: 32px;
+$emoji-picker-header-picture-height: 32px;
+$emoji-picker-emoji-size: 32px;
+
.emoji-picker {
display: flex;
flex-direction: column;
@@ -23,9 +28,11 @@
display: inline-flex;
justify-content: center;
align-items: center;
- width: 30px;
- height: 24px;
- img {
+ width: $emoji-picker-header-picture-width;
+ max-width: $emoji-picker-header-picture-width;
+ height: $emoji-picker-header-picture-height;
+ max-height: $emoji-picker-header-picture-height;
+ .still-image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
@@ -50,7 +57,7 @@
.heading {
display: flex;
- height: 32px;
+ //height: $emoji-picker-header-height;
padding: 10px 7px 5px;
overflow-x: auto;
}
@@ -87,11 +94,19 @@
min-width: 0;
flex-basis: auto;
flex-shrink: 1;
+ display: flex;
+ align-content: center;
&-item {
padding: 0 7px;
cursor: pointer;
font-size: 1.85em;
+ width: $emoji-picker-header-picture-width;
+ max-width: $emoji-picker-header-picture-width;
+ height: $emoji-picker-header-picture-height;
+ max-height: $emoji-picker-header-picture-height;
+ display: flex;
+ align-items: center;
&.disabled {
opacity: 0.5;
@@ -181,11 +196,11 @@
}
&-item {
- width: 32px;
- height: 32px;
+ width: $emoji-picker-emoji-size;
+ height: $emoji-picker-emoji-size;
box-sizing: border-box;
display: flex;
- font-size: 32px;
+ font-size: $emoji-picker-emoji-size;
align-items: center;
justify-content: center;
margin: 4px;
--
cgit v1.2.3-70-g09d2
From 9aeffd7634e049123d3ffc8addf9c223652b0bbb Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 14:46:00 -0400
Subject: Fix sticker picker heading tab
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.scss | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index e315d2d7..ea8b6037 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -57,9 +57,7 @@ $emoji-picker-emoji-size: 32px;
.heading {
display: flex;
- //height: $emoji-picker-header-height;
padding: 10px 7px 5px;
- overflow-x: auto;
}
.content {
@@ -74,6 +72,7 @@ $emoji-picker-emoji-size: 32px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
+ overflow-x: auto;
}
.emoji-groups {
@@ -81,7 +80,8 @@ $emoji-picker-emoji-size: 32px;
}
.additional-tabs {
- display: block;
+ display: flex;
+ flex: 1;
border-left: 1px solid;
border-left-color: $fallback--icon;
border-left-color: var(--icon, $fallback--icon);
@@ -91,9 +91,8 @@ $emoji-picker-emoji-size: 32px;
.additional-tabs,
.emoji-tabs {
- min-width: 0;
flex-basis: auto;
- flex-shrink: 1;
+ // flex-shrink: 1;
display: flex;
align-content: center;
--
cgit v1.2.3-70-g09d2
From 06a636db3732ce2808c54d3b74eb4aabd866dbf6 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 15:09:24 -0400
Subject: Lazy-load emoji picker in post form
When clicking the reply button, we used to load the whole emoji picker.
This causes a considerable delay even if the user is not going to use
the emoji picker. Now the content of the emoji picker is loaded only
after the user has explicitly opened the emoji picker.
Ref: grouped-emoji-picker
---
src/components/emoji_input/emoji_input.vue | 1 +
src/components/emoji_picker/emoji_picker.js | 24 +++++++++++++++++++-----
src/components/emoji_picker/emoji_picker.vue | 9 +++++++--
3 files changed, 27 insertions(+), 7 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index 81b81913..eedde9aa 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -19,6 +19,7 @@
v-if="enableEmojiPicker"
ref="picker"
:class="{ hide: !showPicker }"
+ :showing="showPicker"
:enable-sticker-picker="enableStickerPicker"
class="emoji-picker-panel"
@emoji="insert"
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 5b90c31e..8b4f302f 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -39,6 +39,10 @@ const EmojiPicker = {
required: false,
type: Boolean,
default: false
+ },
+ showing: {
+ required: true,
+ type: Boolean
}
},
data () {
@@ -48,7 +52,9 @@ const EmojiPicker = {
showingStickers: false,
groupsScrolledClass: 'scrolled-top',
keepOpen: false,
- customEmojiTimeout: null
+ customEmojiTimeout: null,
+ // Lazy-load only after the first time `showing` becomes true.
+ contentLoaded: false
}
},
components: {
@@ -115,6 +121,9 @@ const EmojiPicker = {
this.$lozad = lozad('img', {})
this.$lozad.observe()
},
+ waitForDomAndInitializeLazyLoad() {
+ this.$nextTick(() => this.initializeLazyLoad())
+ },
destroyLazyLoad () {
if (this.$lozad) {
if (this.$lozad.observer) {
@@ -129,18 +138,23 @@ const EmojiPicker = {
watch: {
keyword () {
this.onScroll()
- // Wait for the dom to change
- this.$nextTick(() => this.initializeLazyLoad())
+ this.waitForDomAndInitializeLazyLoad()
},
allCustomGroups () {
- this.$nextTick(() => this.initializeLazyLoad())
+ this.waitForDomAndInitializeLazyLoad()
+ },
+ showing (val) {
+ if (val) {
+ this.contentLoaded = true
+ this.waitForDomAndInitializeLazyLoad()
+ }
}
},
mounted () {
if (this.defaultGroup) {
this.highlight(this.defaultGroup)
}
- this.initializeLazyLoad()
+ this.waitForDomAndInitializeLazyLoad()
},
destroyed () {
this.destroyLazyLoad()
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index ed196066..b92bccd7 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -1,5 +1,7 @@
-
+
-
+
Date: Fri, 8 Oct 2021 15:25:13 -0400
Subject: Lint
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 8b4f302f..aeee867d 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -121,7 +121,7 @@ const EmojiPicker = {
this.$lozad = lozad('img', {})
this.$lozad.observe()
},
- waitForDomAndInitializeLazyLoad() {
+ waitForDomAndInitializeLazyLoad () {
this.$nextTick(() => this.initializeLazyLoad())
},
destroyLazyLoad () {
--
cgit v1.2.3-70-g09d2
From d648a6f8dc37a2ceb851f1cecde34fd6c54d7d1f Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 15:30:55 -0400
Subject: Group emojis only by pack and remove pack: prefix
Ref: grouped-emoji-picker
---
src/modules/instance.js | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 8aadce77..a7a91d99 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -116,9 +116,15 @@ const instance = {
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
},
groupedCustomEmojis (state) {
+ const packsOf = emoji => {
+ return emoji.tags
+ .filter(k => k.startsWith('pack:'))
+ .map(k => k.slice(5)) // remove 'pack:' prefix
+ }
+
return state.customEmoji
.reduce((res, emoji) => {
- emoji.tags.forEach(packName => {
+ packsOf(emoji).forEach(packName => {
const packId = `custom-${packName}`
if (!res[packId]) {
res[packId] = ({
--
cgit v1.2.3-70-g09d2
From c93da0b865e9a14c6fa952e63c4c4f77f34943bc Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 8 Oct 2021 15:47:39 -0400
Subject: Fix error on emoji picker first load
Ref: grouped-emoji-picker
---
src/components/emoji_picker/emoji_picker.js | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index aeee867d..ea53a972 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -133,6 +133,18 @@ const EmojiPicker = {
this.$lozad.mutationObserver.disconnect()
}
}
+ },
+ onShowing () {
+ const oldContentLoaded = this.contentLoaded
+ this.contentLoaded = true
+ this.waitForDomAndInitializeLazyLoad()
+ if (!oldContentLoaded) {
+ this.$nextTick(() => {
+ if (this.defaultGroup) {
+ this.highlight(this.defaultGroup)
+ }
+ })
+ }
}
},
watch: {
@@ -145,16 +157,14 @@ const EmojiPicker = {
},
showing (val) {
if (val) {
- this.contentLoaded = true
- this.waitForDomAndInitializeLazyLoad()
+ this.onShowing()
}
}
},
mounted () {
- if (this.defaultGroup) {
- this.highlight(this.defaultGroup)
+ if (this.showing) {
+ this.onShowing()
}
- this.waitForDomAndInitializeLazyLoad()
},
destroyed () {
this.destroyLazyLoad()
--
cgit v1.2.3-70-g09d2
From b77259a9a0c353ede8ff1d6bf5c13ae91ca7fc7c Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sat, 8 Jan 2022 01:35:16 -0500
Subject: Use StillImage to render emojis in emoji picker
---
src/components/emoji_picker/emoji_picker.js | 15 +++++++++++++--
src/components/emoji_picker/emoji_picker.vue | 5 +++--
src/components/still-image/still-image.js | 19 +++++++++++++++++--
src/components/still-image/still-image.vue | 5 +++--
4 files changed, 36 insertions(+), 8 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index ea53a972..315364d5 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -118,8 +118,19 @@ const EmojiPicker = {
},
initializeLazyLoad () {
this.destroyLazyLoad()
- this.$lozad = lozad('img', {})
- this.$lozad.observe()
+ this.$nextTick(() => {
+ this.$lozad = lozad('.still-image.emoji-picker-emoji', {
+ load: el => {
+ const vn = el.__vue__
+ if (!vn) {
+ return
+ }
+
+ vn.loadLazy()
+ }
+ })
+ this.$lozad.observe()
+ })
},
waitForDomAndInitializeLazyLoad () {
this.$nextTick(() => this.initializeLazyLoad())
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index b92bccd7..19cc46b5 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -89,10 +89,11 @@
@click.stop.prevent="onEmoji(emoji)"
>
{{ emoji.replacement }}
-
+ />
diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js
index d7abbcb5..1806d33b 100644
--- a/src/components/still-image/still-image.js
+++ b/src/components/still-image/still-image.js
@@ -7,16 +7,23 @@ const StillImage = {
'imageLoadHandler',
'alt',
'height',
- 'width'
+ 'width',
+ 'dataSrc'
],
data () {
return {
+ // for lazy loading, see loadLazy()
+ realSrc: this.src,
stopGifs: this.$store.getters.mergedConfig.stopGifs
}
},
computed: {
animated () {
- return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif'))
+ if (!this.realSrc) {
+ return false
+ }
+
+ return this.stopGifs && (this.mimetype === 'image/gif' || this.realSrc.endsWith('.gif'))
},
style () {
const appendPx = (str) => /\d$/.test(str) ? str + 'px' : str
@@ -27,7 +34,15 @@ const StillImage = {
}
},
methods: {
+ loadLazy () {
+ if (this.dataSrc) {
+ this.realSrc = this.dataSrc
+ }
+ },
onLoad () {
+ if (!this.realSrc) {
+ return
+ }
const image = this.$refs.src
if (!image) return
this.imageLoadHandler && this.imageLoadHandler(image)
diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue
index ab3080c8..633fb229 100644
--- a/src/components/still-image/still-image.vue
+++ b/src/components/still-image/still-image.vue
@@ -11,10 +11,11 @@
![]()
Date: Sat, 8 Jan 2022 01:37:19 -0500
Subject: Clean up emoji picker css
---
src/components/emoji_picker/emoji_picker.scss | 1 -
1 file changed, 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index ea8b6037..222749d0 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -92,7 +92,6 @@ $emoji-picker-emoji-size: 32px;
.additional-tabs,
.emoji-tabs {
flex-basis: auto;
- // flex-shrink: 1;
display: flex;
align-content: center;
--
cgit v1.2.3-70-g09d2
From 38861fc6cc1e30c6ef3c429db222a303ed1c321d Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Sat, 8 Jan 2022 02:17:59 -0500
Subject: Scroll active tab header into view in emoji picker
---
src/components/emoji_picker/emoji_picker.js | 18 ++++++++++++++++++
src/components/emoji_picker/emoji_picker.vue | 6 +++++-
2 files changed, 23 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 315364d5..26c767ac 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -87,8 +87,26 @@ const EmojiPicker = {
this.activeGroup = group.id
}
})
+ this.scrollHeader()
})
},
+ scrollHeader () {
+ // Scroll the active tab's header into view
+ const headerRef = this.$refs['group-header-' + this.activeGroup][0]
+ const left = headerRef.offsetLeft
+ const right = left + headerRef.offsetWidth
+ const headerCont = this.$refs.header
+ const currentScroll = headerCont.scrollLeft
+ const currentScrollRight = currentScroll + headerCont.clientWidth
+ const setScroll = s => { headerCont.scrollLeft = s }
+
+ const margin = 7 // .emoji-tabs-item: padding
+ if (left - margin < currentScroll) {
+ setScroll(left - margin)
+ } else if (right + margin > currentScrollRight) {
+ setScroll(right + margin - headerCont.clientWidth)
+ }
+ },
highlight (key) {
const ref = this.$refs['group-' + key]
const top = ref.offsetTop
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 19cc46b5..e8d42c24 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -3,9 +3,13 @@
class="emoji-picker panel panel-default panel-body"
>
-
+
Date: Sat, 8 Jan 2022 17:17:32 -0500
Subject: Lint
---
src/components/emoji_picker/emoji_picker.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index bf4a98d4..07f4b005 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -43,7 +43,7 @@ const UNICODE_EMOJI_GROUP_ICON = {
'activities': 'basketball-ball',
'objects': 'lightbulb',
'symbols': 'code',
- 'flags': 'flag',
+ 'flags': 'flag'
}
const filterByKeyword = (list, keyword = '') => {
--
cgit v1.2.3-70-g09d2
From 96564609f87e93d32448da6c7d6a75cea50eff93 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Mon, 17 Jan 2022 23:41:11 -0500
Subject: Make StillImage react to src changes
---
src/components/still-image/still-image.js | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'src')
diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js
index 1806d33b..200ef147 100644
--- a/src/components/still-image/still-image.js
+++ b/src/components/still-image/still-image.js
@@ -57,6 +57,14 @@ const StillImage = {
onError () {
this.imageLoadError && this.imageLoadError()
}
+ },
+ watch: {
+ src () {
+ this.realSrc = this.src
+ },
+ dataSrc () {
+ this.$el.removeAttribute('data-loaded')
+ }
}
}
--
cgit v1.2.3-70-g09d2
From e01c76c7e90f354436e726456532f51288a7ab99 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Wed, 6 Apr 2022 21:29:50 -0400
Subject: Make emoji picker work with vue3
---
src/components/emoji_picker/emoji_picker.js | 21 +++++++++++++++------
src/components/emoji_picker/emoji_picker.vue | 8 +++++---
2 files changed, 20 insertions(+), 9 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 07f4b005..677ef5e4 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -84,7 +84,9 @@ const EmojiPicker = {
keepOpen: false,
customEmojiTimeout: null,
// Lazy-load only after the first time `showing` becomes true.
- contentLoaded: false
+ contentLoaded: false,
+ groupRefs: {},
+ emojiRefs: {}
}
},
components: {
@@ -93,6 +95,12 @@ const EmojiPicker = {
StillImage
},
methods: {
+ setGroupRef (name) {
+ return el => { this.groupRefs[name] = el }
+ },
+ setEmojiRef (name) {
+ return el => { this.emojiRefs[name] = el }
+ },
onStickerUploaded (e) {
this.$emit('sticker-uploaded', e)
},
@@ -112,8 +120,8 @@ const EmojiPicker = {
const top = target.scrollTop + 5
this.$nextTick(() => {
this.allEmojiGroups.forEach(group => {
- const ref = this.$refs['group-' + group.id]
- if (ref[0].offsetTop <= top) {
+ const ref = this.groupRefs['group-' + group.id]
+ if (ref && ref.offsetTop <= top) {
this.activeGroup = group.id
}
})
@@ -122,7 +130,7 @@ const EmojiPicker = {
},
scrollHeader () {
// Scroll the active tab's header into view
- const headerRef = this.$refs['group-header-' + this.activeGroup][0]
+ const headerRef = this.groupRefs['group-header-' + this.activeGroup]
const left = headerRef.offsetLeft
const right = left + headerRef.offsetWidth
const headerCont = this.$refs.header
@@ -138,7 +146,7 @@ const EmojiPicker = {
}
},
highlight (key) {
- const ref = this.$refs['group-' + key]
+ const ref = this.groupRefs['group-' + key]
const top = ref.offsetTop
this.setShowStickers(false)
this.activeGroup = key
@@ -169,7 +177,8 @@ const EmojiPicker = {
this.$nextTick(() => {
this.$lozad = lozad('.still-image.emoji-picker-emoji', {
load: el => {
- const vn = el.__vue__
+ const name = el.getAttribute('data-emoji-name')
+ const vn = this.emojiRefs[name]
if (!vn) {
return
}
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index e8d42c24..a6a63411 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -9,7 +9,7 @@
>
{{ group.text }}
@@ -96,10 +96,12 @@
-
+
--
cgit v1.2.3-70-g09d2
From 0fd0d6c4c2c7791f889135727f8afef10a36472d Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Fri, 29 Apr 2022 22:40:06 -0400
Subject: Limit the width of unsupported multichar emojis
---
src/components/emoji_picker/emoji_picker.scss | 8 ++++++--
src/components/emoji_picker/emoji_picker.vue | 7 +++++--
2 files changed, 11 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index 222749d0..af01b3ec 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -198,18 +198,22 @@ $emoji-picker-emoji-size: 32px;
height: $emoji-picker-emoji-size;
box-sizing: border-box;
display: flex;
- font-size: $emoji-picker-emoji-size;
+ line-height: $emoji-picker-emoji-size;
align-items: center;
justify-content: center;
margin: 4px;
cursor: pointer;
- img {
+ .emoji-picker-emoji.-custom {
object-fit: contain;
max-width: 100%;
max-height: 100%;
}
+ .emoji-picker-emoji.-unicode {
+ font-size: 24px;
+ overflow: hidden;
+ }
}
}
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index a6a63411..e5a5958c 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -92,10 +92,13 @@
class="emoji-item"
@click.stop.prevent="onEmoji(emoji)"
>
- {{ emoji.replacement }}
+ {{ emoji.replacement }}
Date: Mon, 20 Jun 2022 08:50:32 -0400
Subject: Use trimmed keyword for filtering emojis
---
src/components/emoji_picker/emoji_picker.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 677ef5e4..3cb6f76d 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -270,7 +270,7 @@ const EmojiPicker = {
return this.allEmojiGroups
.map(group => ({
...group,
- emojis: filterByKeyword(group.emojis, this.keyword)
+ emojis: filterByKeyword(group.emojis, trim(this.keyword))
}))
.filter(group => group.emojis.length > 0)
},
--
cgit v1.2.3-70-g09d2
From 5d6f3a5c8bd3acc53e51b4300c93051ddc1b627b Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Thu, 7 Jul 2022 23:10:06 -0400
Subject: Tweak efficiency when changing filter keywords in emoji picker
---
src/components/emoji_picker/emoji_picker.js | 31 +++++++++++++++++++----------
1 file changed, 20 insertions(+), 11 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 3cb6f76d..6a7b5285 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -17,7 +17,7 @@ import {
faCode,
faFlag
} from '@fortawesome/free-solid-svg-icons'
-import { trim } from 'lodash'
+import { debounce, trim } from 'lodash'
library.add(
faBoxOpen,
@@ -86,7 +86,8 @@ const EmojiPicker = {
// Lazy-load only after the first time `showing` becomes true.
contentLoaded: false,
groupRefs: {},
- emojiRefs: {}
+ emojiRefs: {},
+ filteredEmojiGroups: []
}
},
components: {
@@ -206,6 +207,7 @@ const EmojiPicker = {
const oldContentLoaded = this.contentLoaded
this.contentLoaded = true
this.waitForDomAndInitializeLazyLoad()
+ this.filteredEmojiGroups = this.getFilteredEmojiGroups()
if (!oldContentLoaded) {
this.$nextTick(() => {
if (this.defaultGroup) {
@@ -213,15 +215,24 @@ const EmojiPicker = {
}
})
}
+ },
+ getFilteredEmojiGroups () {
+ return this.allEmojiGroups
+ .map(group => ({
+ ...group,
+ emojis: filterByKeyword(group.emojis, trim(this.keyword))
+ }))
+ .filter(group => group.emojis.length > 0)
}
},
watch: {
keyword () {
this.onScroll()
- this.waitForDomAndInitializeLazyLoad()
+ this.debouncedHandleKeywordChange()
},
allCustomGroups () {
this.waitForDomAndInitializeLazyLoad()
+ this.filteredEmojiGroups = this.getFilteredEmojiGroups()
},
showing (val) {
if (val) {
@@ -266,16 +277,14 @@ const EmojiPicker = {
.map(([_, v]) => v)
.concat(this.unicodeEmojiGroups)
},
- filteredEmojiGroups () {
- return this.allEmojiGroups
- .map(group => ({
- ...group,
- emojis: filterByKeyword(group.emojis, trim(this.keyword))
- }))
- .filter(group => group.emojis.length > 0)
- },
stickerPickerEnabled () {
return (this.$store.state.instance.stickers || []).length !== 0
+ },
+ debouncedHandleKeywordChange () {
+ return debounce(() => {
+ this.waitForDomAndInitializeLazyLoad()
+ this.filteredEmojiGroups = this.getFilteredEmojiGroups()
+ }, 500)
}
}
}
--
cgit v1.2.3-70-g09d2
From 58b01db9e1f466607b810b1900db1d8e4411ccad Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Mon, 1 Aug 2022 11:03:52 -0400
Subject: Fix emoji picker lint
---
src/components/emoji_picker/emoji_picker.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 6a7b5285..c2ae76f3 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -40,10 +40,10 @@ const UNICODE_EMOJI_GROUP_ICON = {
'animals-and-nature': 'paw',
'food-and-drink': 'ice-cream',
'travel-and-places': 'bus',
- 'activities': 'basketball-ball',
- 'objects': 'lightbulb',
- 'symbols': 'code',
- 'flags': 'flag'
+ activities: 'basketball-ball',
+ objects: 'lightbulb',
+ symbols: 'code',
+ flags: 'flag'
}
const filterByKeyword = (list, keyword = '') => {
--
cgit v1.2.3-70-g09d2
From 6e2b87f5af922d27ee87b9fec64c5308832a41af Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Mon, 1 Aug 2022 11:30:54 -0400
Subject: Fix emoji picker lint
---
src/components/emoji_picker/emoji_picker.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index e5a5958c..689138e6 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -98,8 +98,8 @@
>{{ emoji.replacement }}
--
cgit v1.2.3-70-g09d2
From 8bd27165f38e8568950992bc82058da676e56f18 Mon Sep 17 00:00:00 2001
From: HJ <30-hj@users.noreply.git.pleroma.social>
Date: Thu, 18 Aug 2022 13:10:24 +0000
Subject: Fix non-square emojis being truncated
---
src/components/emoji_picker/emoji_picker.scss | 2 ++
1 file changed, 2 insertions(+)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss
index af01b3ec..016c46d7 100644
--- a/src/components/emoji_picker/emoji_picker.scss
+++ b/src/components/emoji_picker/emoji_picker.scss
@@ -35,6 +35,8 @@ $emoji-picker-emoji-size: 32px;
.still-image {
max-width: 100%;
max-height: 100%;
+ height: 100%;
+ width: 100%;
object-fit: contain;
}
}
--
cgit v1.2.3-70-g09d2
From 0445d7c882a5b1d213b0ff5e54e91d6225101c66 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Wed, 31 Aug 2022 16:03:15 -0400
Subject: Make unicode emoji phrases match with _
---
src/modules/instance.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 2fcb059c..9df01bfd 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -190,7 +190,7 @@ const instance = {
const values = await res.json()
const emoji = Object.keys(values).reduce((res, groupId) => {
res[groupId] = values[groupId].map(e => ({
- displayText: e.name,
+ displayText: e.slug,
imageUrl: false,
replacement: e.emoji
}))
--
cgit v1.2.3-70-g09d2
From fa1d9f3fb4a886cde2553739f5f9a83aa35f2fdd Mon Sep 17 00:00:00 2001
From: Henry Jameson
Date: Tue, 20 Sep 2022 00:24:08 +0300
Subject: using the half-shit approach since proper approach is full-shit
---
src/components/update_notification/update_notification.js | 15 +++++----------
.../update_notification/update_notification.scss | 12 +++++++++---
.../update_notification/update_notification.vue | 7 +++++--
3 files changed, 19 insertions(+), 15 deletions(-)
(limited to 'src')
diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js
index 06241688..ddf379f5 100644
--- a/src/components/update_notification/update_notification.js
+++ b/src/components/update_notification/update_notification.js
@@ -17,9 +17,9 @@ export const CURRENT_UPDATE_COUNTER = 1
const UpdateNotification = {
data () {
return {
+ showingImage: false,
pleromaTanVariant: Math.random() > 0.5 ? pleromaTan : pleromaTanFox,
- showingMore: false,
- contentHeight: 0
+ showingMore: false
}
},
components: {
@@ -32,11 +32,6 @@ const UpdateNotification = {
'shape-outside': 'url(' + mask + ')'
}
},
- dynamicStyles () {
- return {
- '--____extraInfoGroupHeight': this.contentHeight + 'px'
- }
- },
shouldShow () {
return !this.$store.state.instance.disableUpdateNotification &&
this.$store.state.users.currentUser &&
@@ -60,12 +55,12 @@ const UpdateNotification = {
}
},
mounted () {
+ this.contentHeightNoImage = this.$refs.animatedText.scrollHeight
+
// Workaround to get the text height only after mask loaded. A bit hacky.
const newImg = new Image()
newImg.onload = () => {
- setTimeout(() => {
- this.contentHeight = this.$refs.animatedText.scrollHeight
- }, 100)
+ setTimeout(() => { this.showingImage = true }, 100)
}
newImg.src = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask
}
diff --git a/src/components/update_notification/update_notification.scss b/src/components/update_notification/update_notification.scss
index 8cad1bc7..ce8129d0 100644
--- a/src/components/update_notification/update_notification.scss
+++ b/src/components/update_notification/update_notification.scss
@@ -35,6 +35,12 @@
margin-top: calc(-1 * var(--__top-fringe));
margin-bottom: calc(-1 * var(--__bottom-fringe));
margin-right: calc(-1 * var(--__right-fringe));
+
+ &.-noImage {
+ .text {
+ padding-right: var(--__right-fringe);
+ }
+ }
}
.panel-body {
@@ -75,9 +81,9 @@
.extra-info-group {
transition: max-height, padding, height;
- transition-timing-function: ease-in-out;
- transition-duration: 500ms;
- max-height: calc(var(--____extraInfoGroupHeight) + 1em); // include bottom padding
+ transition-timing-function: ease-in;
+ transition-duration: 700ms;
+ max-height: 70vh;
mask:
linear-gradient(to top, white, transparent) bottom/100% 2px no-repeat,
linear-gradient(to top, white, white);
diff --git a/src/components/update_notification/update_notification.vue b/src/components/update_notification/update_notification.vue
index 00841af2..78e70a74 100644
--- a/src/components/update_notification/update_notification.vue
+++ b/src/components/update_notification/update_notification.vue
@@ -7,7 +7,6 @@
@@ -15,8 +14,12 @@
-
+
![]()
Date: Tue, 20 Sep 2022 19:27:26 -0400
Subject: Extract language list to its own file
---
package.json | 5 +++--
src/i18n/languages.js | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/i18n/messages.js | 45 ++++++++++++---------------------------------
yarn.lock | 5 +++++
4 files changed, 64 insertions(+), 35 deletions(-)
create mode 100644 src/i18n/languages.js
(limited to 'src')
diff --git a/package.json b/package.json
index 5a2407c6..b0c06a61 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@fortawesome/free-solid-svg-icons": "6.2.0",
"@fortawesome/vue-fontawesome": "3.0.1",
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
+ "@kazvmoe-infra/unicode-emoji-json": "^0.4.0",
"@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12",
"@vuelidate/core": "2.0.0-alpha.44",
"@vuelidate/validators": "2.0.0-alpha.31",
@@ -34,8 +35,8 @@
"escape-html": "1.0.3",
"js-cookie": "3.0.1",
"localforage": "1.10.0",
- "parse-link-header": "2.0.0",
"lozad": "^1.16.0",
+ "parse-link-header": "2.0.0",
"phoenix": "1.6.2",
"punycode.js": "2.1.0",
"qrcode": "1.5.0",
@@ -116,8 +117,8 @@
"stylelint": "13.13.1",
"stylelint-config-standard": "20.0.0",
"stylelint-rscss": "0.4.0",
- "vue-loader": "17.0.0",
"unicode-emoji-json": "^0.3.0",
+ "vue-loader": "17.0.0",
"vue-style-loader": "4.1.3",
"webpack": "5.74.0",
"webpack-dev-middleware": "3.7.3",
diff --git a/src/i18n/languages.js b/src/i18n/languages.js
new file mode 100644
index 00000000..b1cb1d7e
--- /dev/null
+++ b/src/i18n/languages.js
@@ -0,0 +1,44 @@
+
+const languages = [
+ 'ar',
+ 'ca',
+ 'cs',
+ 'de',
+ 'eo',
+ 'en',
+ 'es',
+ 'et',
+ 'eu',
+ 'fi',
+ 'fr',
+ 'ga',
+ 'he',
+ 'hu',
+ 'it',
+ 'ja',
+ 'ja_easy',
+ 'ko',
+ 'nb',
+ 'nl',
+ 'oc',
+ 'pl',
+ 'pt',
+ 'ro',
+ 'ru',
+ 'sk',
+ 'te',
+ 'uk',
+ 'zh',
+ 'zh_Hant'
+]
+
+const specialJsonName = {
+ ja: 'ja_pedantic'
+}
+
+const langCodeToJsonName = (code) => specialJsonName[code] || code
+
+module.exports = {
+ languages,
+ langCodeToJsonName
+}
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index eae75c80..8cf25973 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -7,46 +7,25 @@
// sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json
// There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry.
-const loaders = {
- ar: () => import('./ar.json'),
- ca: () => import('./ca.json'),
- cs: () => import('./cs.json'),
- de: () => import('./de.json'),
- eo: () => import('./eo.json'),
- es: () => import('./es.json'),
- et: () => import('./et.json'),
- eu: () => import('./eu.json'),
- fi: () => import('./fi.json'),
- fr: () => import('./fr.json'),
- ga: () => import('./ga.json'),
- he: () => import('./he.json'),
- hu: () => import('./hu.json'),
- it: () => import('./it.json'),
- ja: () => import('./ja_pedantic.json'),
- ja_easy: () => import('./ja_easy.json'),
- ko: () => import('./ko.json'),
- nb: () => import('./nb.json'),
- nl: () => import('./nl.json'),
- oc: () => import('./oc.json'),
- pl: () => import('./pl.json'),
- pt: () => import('./pt.json'),
- ro: () => import('./ro.json'),
- ru: () => import('./ru.json'),
- sk: () => import('./sk.json'),
- te: () => import('./te.json'),
- uk: () => import('./uk.json'),
- zh: () => import('./zh.json'),
- zh_Hant: () => import('./zh_Hant.json')
+import { languages, langCodeToJsonName } from './languages.js'
+
+const hasLanguageFile = (code) => languages.includes(code)
+
+const loadLanguageFile = (code) => {
+ return import(
+ /* webpackInclude: /\.json$/ */
+ `./${langCodeToJsonName(code)}.json`
+ )
}
const messages = {
- languages: ['en', ...Object.keys(loaders)],
+ languages,
default: {
en: require('./en.json').default
},
setLanguage: async (i18n, language) => {
- if (loaders[language]) {
- const messages = await loaders[language]()
+ if (hasLanguageFile(language)) {
+ const messages = await loadLanguageFile(language)
i18n.setLocaleMessage(language, messages.default)
}
i18n.locale = language
diff --git a/yarn.lock b/yarn.lock
index a971bf9a..f1cfc7f3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1629,6 +1629,11 @@
dependencies:
pointer-tracker "^2.0.3"
+"@kazvmoe-infra/unicode-emoji-json@^0.4.0":
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/@kazvmoe-infra/unicode-emoji-json/-/unicode-emoji-json-0.4.0.tgz#555bab2f8d11db74820ef0a2fbe2805b17c22587"
+ integrity sha512-22OffREdHzD0U6A/W4RaFPV8NR73za6euibtAxNxO/fu5A6TwxRO2lAdbDWKJH9COv/vYs8zqfEiSalXH2nXJA==
+
"@nightwatch/chai@5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@nightwatch/chai/-/chai-5.0.2.tgz#86b20908fc090dffd5c9567c0392bc6a494cc2e6"
--
cgit v1.2.3-70-g09d2
From 1c3bdda14c0edf4ce321745bcf43e395635d6bf1 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 20:15:32 -0400
Subject: Load unicode emoji annotations
---
src/i18n/languages.js | 10 +++++++++-
src/modules/config.js | 1 +
src/modules/instance.js | 24 ++++++++++++++++++++++++
3 files changed, 34 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/i18n/languages.js b/src/i18n/languages.js
index b1cb1d7e..40cf04f2 100644
--- a/src/i18n/languages.js
+++ b/src/i18n/languages.js
@@ -38,7 +38,15 @@ const specialJsonName = {
const langCodeToJsonName = (code) => specialJsonName[code] || code
+const langCodeToCldrName = (code) => code
+
+const ensureFinalFallback = codes => {
+ return codes.includes('en') ? codes : codes.concat(['en'])
+}
+
module.exports = {
languages,
- langCodeToJsonName
+ langCodeToJsonName,
+ langCodeToCldrName,
+ ensureFinalFallback
}
diff --git a/src/modules/config.js b/src/modules/config.js
index eeaac917..c966602e 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -183,6 +183,7 @@ const config = {
break
case 'interfaceLanguage':
messages.setLanguage(this.getters.i18n, value)
+ dispatch('loadUnicodeEmojiData', value)
Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value))
break
case 'thirdColumnMode':
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 9df01bfd..c0c7cef0 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -2,6 +2,7 @@ import { getPreset, applyTheme } from '../services/style_setter/style_setter.js'
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
import apiService from '../services/api/api.service.js'
import { instanceDefaultProperties } from './config.js'
+import { langCodeToCldrName, ensureFinalFallback } from '../i18n/languages.js'
const SORTED_EMOJI_GROUP_IDS = [
'smileys-and-emotion',
@@ -78,6 +79,7 @@ const defaultState = {
customEmojiFetched: false,
emoji: {},
emojiFetched: false,
+ unicodeEmojiAnnotations: {},
pleromaBackend: true,
postFormats: [],
restrictedNicknames: [],
@@ -109,6 +111,12 @@ const defaultState = {
}
}
+const loadAnnotations = (lang) => {
+ return import(
+ `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json`
+ )
+}
+
const instance = {
state: defaultState,
mutations: {
@@ -119,6 +127,9 @@ const instance = {
},
setKnownDomains (state, domains) {
state.knownDomains = domains
+ },
+ setUnicodeEmojiAnnotations (state, { lang, annotations }) {
+ state.unicodeEmojiAnnotations[lang] = annotations
}
},
getters: {
@@ -206,6 +217,19 @@ const instance = {
}
},
+ loadUnicodeEmojiData ({ commit, state }, language) {
+ const langList = ensureFinalFallback(Array.isArray(language) ? language : [language])
+
+ return Promise.all(
+ langList
+ .forEach(async lang => {
+ if (!state.unicodeEmojiAnnotations[lang]) {
+ const annotations = await loadAnnotations(lang)
+ commit('setUnicodeEmojiAnnotations', { lang, annotations })
+ }
+ }))
+ },
+
async getCustomEmoji ({ commit, state }) {
try {
const res = await window.fetch('/api/pleroma/emoji.json')
--
cgit v1.2.3-70-g09d2
From a73f9731f5ad78d1e6f1bd211ad2971d21fc1379 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 20:44:52 -0400
Subject: Display localized unicode emoji names
---
src/components/emoji_picker/emoji_picker.js | 20 ++++++++++++++++++++
src/components/emoji_picker/emoji_picker.vue | 2 +-
src/i18n/languages.js | 3 ++-
src/modules/instance.js | 18 +++++++++++++++---
4 files changed, 38 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index c2ae76f3..2ebead53 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,6 +1,7 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
import StillImage from '../still-image/still-image.vue'
+import { ensureFinalFallback } from '../../i18n/languages.js'
import lozad from 'lozad'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -285,6 +286,25 @@ const EmojiPicker = {
this.waitForDomAndInitializeLazyLoad()
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
}, 500)
+ },
+ languages () {
+ console.log('languages:', ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage))
+ return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)
+ },
+ maybeLocalizedEmojiName () {
+ return emoji => {
+ if (!emoji.annotations) {
+ return emoji.displayText
+ }
+
+ for (const lang of this.languages) {
+ if (emoji.annotations[lang]?.name) {
+ return emoji.annotations[lang].name
+ }
+ }
+
+ return emoji.displayText
+ }
}
}
}
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 689138e6..57bb0037 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -88,7 +88,7 @@
diff --git a/src/i18n/languages.js b/src/i18n/languages.js
index 40cf04f2..250b3b1a 100644
--- a/src/i18n/languages.js
+++ b/src/i18n/languages.js
@@ -41,7 +41,8 @@ const langCodeToJsonName = (code) => specialJsonName[code] || code
const langCodeToCldrName = (code) => code
const ensureFinalFallback = codes => {
- return codes.includes('en') ? codes : codes.concat(['en'])
+ const codeList = Array.isArray(codes) ? codes : [codes]
+ return codeList.includes('en') ? codeList : codeList.concat(['en'])
}
module.exports = {
diff --git a/src/modules/instance.js b/src/modules/instance.js
index c0c7cef0..5a72a6d3 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -117,6 +117,18 @@ const loadAnnotations = (lang) => {
)
}
+const injectAnnotations = (emoji, annotations) => {
+ const availableLangs = Object.keys(annotations)
+
+ return {
+ ...emoji,
+ annotations: availableLangs.reduce((acc, cur) => {
+ acc[cur] = annotations[cur][emoji.replacement]
+ return acc
+ }, {})
+ }
+}
+
const instance = {
state: defaultState,
mutations: {
@@ -164,13 +176,13 @@ const instance = {
},
standardEmojiList (state) {
return SORTED_EMOJI_GROUP_IDS
- .map(groupId => state.emoji[groupId] || [])
+ .map(groupId => (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations)))
.reduce((a, b) => a.concat(b), [])
},
standardEmojiGroupList (state) {
return SORTED_EMOJI_GROUP_IDS.map(groupId => ({
id: groupId,
- emojis: state.emoji[groupId] || []
+ emojis: (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations))
}))
},
instanceDomain (state) {
@@ -218,7 +230,7 @@ const instance = {
},
loadUnicodeEmojiData ({ commit, state }, language) {
- const langList = ensureFinalFallback(Array.isArray(language) ? language : [language])
+ const langList = ensureFinalFallback(language)
return Promise.all(
langList
--
cgit v1.2.3-70-g09d2
From 980241c1ac4044e66a4f702d5420affc4a3bb9a0 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 21:06:57 -0400
Subject: Support filtering by keywords from cldr
---
src/components/emoji_picker/emoji_picker.js | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 2ebead53..bf5e0e43 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -47,13 +47,30 @@ const UNICODE_EMOJI_GROUP_ICON = {
flags: 'flag'
}
-const filterByKeyword = (list, keyword = '') => {
+const maybeLocalizedKeywords = (emoji, languages) => {
+ const res = [emoji.displayText]
+ if (emoji.annotations) {
+ languages.forEach(lang => {
+ const keywords = emoji.annotations[lang]?.keywords || []
+ const name = emoji.annotations[lang]?.name
+ res.push(...(keywords.concat([name]).filter(k => k)))
+ })
+ }
+ return res
+}
+
+const filterByKeyword = (list, keyword = '', languages) => {
if (keyword === '') return list
const keywordLowercase = keyword.toLowerCase()
const orderedEmojiList = []
for (const emoji of list) {
- const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase)
+ const indices = maybeLocalizedKeywords(emoji, languages)
+ .map(k => k.toLowerCase().indexOf(keywordLowercase))
+ .filter(k => k > -1)
+
+ const indexOfKeyword = indices.length ? Math.min(...indices) : -1
+
if (indexOfKeyword > -1) {
if (!Array.isArray(orderedEmojiList[indexOfKeyword])) {
orderedEmojiList[indexOfKeyword] = []
@@ -172,7 +189,7 @@ const EmojiPicker = {
this.showingStickers = value
},
filterByKeyword (list, keyword) {
- return filterByKeyword(list, keyword)
+ return filterByKeyword(list, keyword, this.languages)
},
initializeLazyLoad () {
this.destroyLazyLoad()
@@ -221,7 +238,7 @@ const EmojiPicker = {
return this.allEmojiGroups
.map(group => ({
...group,
- emojis: filterByKeyword(group.emojis, trim(this.keyword))
+ emojis: this.filterByKeyword(group.emojis, trim(this.keyword))
}))
.filter(group => group.emojis.length > 0)
}
--
cgit v1.2.3-70-g09d2
From cc58b9b93d4346860e244d2093f0d406eb76954c Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 21:50:40 -0400
Subject: Add regional indicators
---
src/components/emoji_picker/emoji_picker.js | 15 +++++++++------
src/i18n/en.json | 3 ++-
src/modules/instance.js | 29 +++++++++++++++++++++++++++--
3 files changed, 38 insertions(+), 9 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index bf5e0e43..fafc2af1 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -47,8 +47,8 @@ const UNICODE_EMOJI_GROUP_ICON = {
flags: 'flag'
}
-const maybeLocalizedKeywords = (emoji, languages) => {
- const res = [emoji.displayText]
+const maybeLocalizedKeywords = (emoji, languages, nameLocalizer) => {
+ const res = [emoji.displayText, nameLocalizer(emoji)]
if (emoji.annotations) {
languages.forEach(lang => {
const keywords = emoji.annotations[lang]?.keywords || []
@@ -59,13 +59,13 @@ const maybeLocalizedKeywords = (emoji, languages) => {
return res
}
-const filterByKeyword = (list, keyword = '', languages) => {
+const filterByKeyword = (list, keyword = '', languages, nameLocalizer) => {
if (keyword === '') return list
const keywordLowercase = keyword.toLowerCase()
const orderedEmojiList = []
for (const emoji of list) {
- const indices = maybeLocalizedKeywords(emoji, languages)
+ const indices = maybeLocalizedKeywords(emoji, languages, nameLocalizer)
.map(k => k.toLowerCase().indexOf(keywordLowercase))
.filter(k => k > -1)
@@ -189,7 +189,7 @@ const EmojiPicker = {
this.showingStickers = value
},
filterByKeyword (list, keyword) {
- return filterByKeyword(list, keyword, this.languages)
+ return filterByKeyword(list, keyword, this.languages, this.maybeLocalizedEmojiName)
},
initializeLazyLoad () {
this.destroyLazyLoad()
@@ -305,7 +305,6 @@ const EmojiPicker = {
}, 500)
},
languages () {
- console.log('languages:', ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage))
return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)
},
maybeLocalizedEmojiName () {
@@ -314,6 +313,10 @@ const EmojiPicker = {
return emoji.displayText
}
+ if (emoji.displayTextI18n) {
+ return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)
+ }
+
for (const lang of this.languages) {
if (emoji.annotations[lang]?.name) {
return emoji.annotations[lang].name
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 2a665bd5..fb941c8d 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -211,7 +211,8 @@
"travel-and-places": "Travel & Places"
},
"load_all_hint": "Loaded first {saneAmount} emoji, loading all emoji may cause performance issues.",
- "load_all": "Loading all {emojiAmount} emoji"
+ "load_all": "Loading all {emojiAmount} emoji",
+ "regional_indicator": "Regional indicator {letter}"
},
"errors": {
"storage_unavailable": "Pleroma could not access browser storage. Your login or your local settings won't be saved and you might encounter unexpected issues. Try enabling cookies."
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 5a72a6d3..9be35d88 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -16,6 +16,26 @@ const SORTED_EMOJI_GROUP_IDS = [
'flags'
]
+const REGIONAL_INDICATORS = (() => {
+ const start = 0x1F1E6
+ const end = 0x1F1FF
+ const A = 'A'.codePointAt(0)
+ const res = new Array(end - start + 1)
+ for (let i = start; i <= end; ++i) {
+ const letter = String.fromCodePoint(A + i - start)
+ res[i - start] = {
+ replacement: String.fromCodePoint(i),
+ imageUrl: false,
+ displayText: 'regional_indicator_' + letter,
+ displayTextI18n: {
+ key: 'emoji.regional_indicator',
+ args: { letter }
+ }
+ }
+ }
+ return res
+})()
+
const defaultState = {
// Stuff from apiConfig
name: 'Pleroma FE',
@@ -129,6 +149,11 @@ const injectAnnotations = (emoji, annotations) => {
}
}
+const injectRegionalIndicators = groups => {
+ groups.symbols.push(...REGIONAL_INDICATORS)
+ return groups
+}
+
const instance = {
state: defaultState,
mutations: {
@@ -219,7 +244,7 @@ const instance = {
}))
return res
}, {})
- commit('setInstanceOption', { name: 'emoji', value: emoji })
+ commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) })
} else {
throw (res)
}
@@ -234,7 +259,7 @@ const instance = {
return Promise.all(
langList
- .forEach(async lang => {
+ .map(async lang => {
if (!state.unicodeEmojiAnnotations[lang]) {
const annotations = await loadAnnotations(lang)
commit('setUnicodeEmojiAnnotations', { lang, annotations })
--
cgit v1.2.3-70-g09d2
From 6fab7b9e3ffb4a9bce2788174ef0e9e6eef7b2c5 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 22:03:31 -0400
Subject: Use import() for emoji.json
---
build/update-emoji.js | 2 +-
package.json | 1 -
src/modules/instance.js | 27 ++++++++++++---------------
yarn.lock | 5 -----
4 files changed, 13 insertions(+), 22 deletions(-)
(limited to 'src')
diff --git a/build/update-emoji.js b/build/update-emoji.js
index fba7706e..9f4b4e67 100644
--- a/build/update-emoji.js
+++ b/build/update-emoji.js
@@ -1,7 +1,7 @@
module.exports = {
updateEmoji () {
- const emojis = require('unicode-emoji-json/data-by-group')
+ const emojis = require('@kazvmoe-infra/unicode-emoji-json/data-by-group')
const fs = require('fs')
Object.keys(emojis)
diff --git a/package.json b/package.json
index b0c06a61..260df573 100644
--- a/package.json
+++ b/package.json
@@ -117,7 +117,6 @@
"stylelint": "13.13.1",
"stylelint-config-standard": "20.0.0",
"stylelint-rscss": "0.4.0",
- "unicode-emoji-json": "^0.3.0",
"vue-loader": "17.0.0",
"vue-style-loader": "4.1.3",
"webpack": "5.74.0",
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 9be35d88..9f326d26 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -135,6 +135,7 @@ const loadAnnotations = (lang) => {
return import(
`@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json`
)
+ .then(k => k.default)
}
const injectAnnotations = (emoji, annotations) => {
@@ -233,21 +234,17 @@ const instance = {
},
async getStaticEmoji ({ commit }) {
try {
- const res = await window.fetch('/static/emoji.json')
- if (res.ok) {
- const values = await res.json()
- const emoji = Object.keys(values).reduce((res, groupId) => {
- res[groupId] = values[groupId].map(e => ({
- displayText: e.slug,
- imageUrl: false,
- replacement: e.emoji
- }))
- return res
- }, {})
- commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) })
- } else {
- throw (res)
- }
+ const values = (await import('../../static/emoji.json')).default
+
+ const emoji = Object.keys(values).reduce((res, groupId) => {
+ res[groupId] = values[groupId].map(e => ({
+ displayText: e.slug,
+ imageUrl: false,
+ replacement: e.emoji
+ }))
+ return res
+ }, {})
+ commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) })
} catch (e) {
console.warn("Can't load static emoji")
console.warn(e)
diff --git a/yarn.lock b/yarn.lock
index f1cfc7f3..a22ab65d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8138,11 +8138,6 @@ unicode-canonical-property-names-ecmascript@^2.0.0:
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==
-unicode-emoji-json@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/unicode-emoji-json/-/unicode-emoji-json-0.3.0.tgz#965e097ef8a367081c5036f81873015a95a5c1ad"
- integrity sha512-yImheILedqhZtVEEenRELu9AnX347ZTA3bVMWAU5WMUv7pdU2hcfpwo2mKN8Rns9uHLmOZP90/4B4SPS5aF/iw==
-
unicode-match-property-ecmascript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3"
--
cgit v1.2.3-70-g09d2
From a758e18dceb4cb11d84d6dff1cdfddb755af60db Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Tue, 20 Sep 2022 23:13:07 -0400
Subject: Make chunks named
---
.babelrc | 2 +-
build/webpack.base.conf.js | 3 ++-
src/i18n/messages.js | 1 +
src/modules/instance.js | 3 ++-
4 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'src')
diff --git a/.babelrc b/.babelrc
index 373d2c59..4ec10416 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,5 +1,5 @@
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"],
- "comments": false
+ "comments": true
}
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 78b75e3f..bf946922 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -24,7 +24,8 @@ module.exports = {
output: {
path: config.build.assetsRoot,
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
- filename: '[name].js'
+ filename: '[name].js',
+ chunkFilename: '[name].js'
},
optimization: {
splitChunks: {
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 8cf25973..74a89ca8 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -14,6 +14,7 @@ const hasLanguageFile = (code) => languages.includes(code)
const loadLanguageFile = (code) => {
return import(
/* webpackInclude: /\.json$/ */
+ /* webpackChunkName: "i18n/[request]" */
`./${langCodeToJsonName(code)}.json`
)
}
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 9f326d26..b1bc9779 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -133,6 +133,7 @@ const defaultState = {
const loadAnnotations = (lang) => {
return import(
+ /* webpackChunkName: "emoji-annotations/[request]" */
`@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json`
)
.then(k => k.default)
@@ -234,7 +235,7 @@ const instance = {
},
async getStaticEmoji ({ commit }) {
try {
- const values = (await import('../../static/emoji.json')).default
+ const values = (await import(/* webpackChunkName: 'emoji' */ '../../static/emoji.json')).default
const emoji = Object.keys(values).reduce((res, groupId) => {
res[groupId] = values[groupId].map(e => ({
--
cgit v1.2.3-70-g09d2
From a7f836a64e334d6c46ed1e12c7bf9b2ff4a09c7e Mon Sep 17 00:00:00 2001
From: Tusooa Zhu
Date: Wed, 21 Sep 2022 23:16:33 -0400
Subject: Make suggestor suggest according to cldr annotations
---
src/components/emoji_input/emoji_input.js | 49 ++++++++++++++++++++++++++++--
src/components/emoji_input/emoji_input.vue | 2 +-
src/components/emoji_input/suggestor.js | 32 +++++++++----------
3 files changed, 64 insertions(+), 19 deletions(-)
(limited to 'src')
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index fb2096c9..ffc0ffac 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -3,7 +3,7 @@ import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
import { take } from 'lodash'
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
-
+import { ensureFinalFallback } from '../../i18n/languages.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSmileBeam
@@ -143,6 +143,51 @@ const EmojiInput = {
const word = Completion.wordAtPosition(this.modelValue, this.caret - 1) || {}
return word
}
+ },
+ languages () {
+ return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)
+ },
+ maybeLocalizedEmojiNamesAndKeywords () {
+ return emoji => {
+ const names = [emoji.displayText]
+ const keywords = []
+
+ if (emoji.displayTextI18n) {
+ names.push(this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args))
+ }
+
+ if (emoji.annotations) {
+ this.languages.forEach(lang => {
+ names.push(emoji.annotations[lang]?.name)
+
+ keywords.push(...(emoji.annotations[lang]?.keywords || []))
+ })
+ }
+
+ return {
+ names: names.filter(k => k),
+ keywords: keywords.filter(k => k)
+ }
+ }
+ },
+ maybeLocalizedEmojiName () {
+ return emoji => {
+ if (!emoji.annotations) {
+ return emoji.displayText
+ }
+
+ if (emoji.displayTextI18n) {
+ return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)
+ }
+
+ for (const lang of this.languages) {
+ if (emoji.annotations[lang]?.name) {
+ return emoji.annotations[lang].name
+ }
+ }
+
+ return emoji.displayText
+ }
}
},
mounted () {
@@ -181,7 +226,7 @@ const EmojiInput = {
const firstchar = newWord.charAt(0)
this.suggestions = []
if (newWord === firstchar) return
- const matchedSuggestions = await this.suggest(newWord)
+ const matchedSuggestions = await this.suggest(newWord, this.maybeLocalizedEmojiNamesAndKeywords)
// Async: cancel if textAtCaret has changed during wait
if (this.textAtCaret !== newWord) return
if (matchedSuggestions.length <= 0) return
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index eedde9aa..43581dbf 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -64,7 +64,7 @@
v-if="!suggestion.user"
class="displayText"
>
- {{ suggestion.displayText }}
+ {{ maybeLocalizedEmojiName(suggestion) }}
{{ suggestion.detailText }}
diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js
index 1765f843..adaa879e 100644
--- a/src/components/emoji_input/suggestor.js
+++ b/src/components/emoji_input/suggestor.js
@@ -13,10 +13,10 @@
export default data => {
const emojiCurry = suggestEmoji(data.emoji)
const usersCurry = data.store && suggestUsers(data.store)
- return input => {
+ return (input, nameKeywordLocalizer) => {
const firstChar = input[0]
if (firstChar === ':' && data.emoji) {
- return emojiCurry(input)
+ return emojiCurry(input, nameKeywordLocalizer)
}
if (firstChar === '@' && usersCurry) {
return usersCurry(input)
@@ -25,34 +25,34 @@ export default data => {
}
}
-export const suggestEmoji = emojis => input => {
+export const suggestEmoji = emojis => (input, nameKeywordLocalizer) => {
const noPrefix = input.toLowerCase().substr(1)
return emojis
- .filter(({ displayText }) => displayText.toLowerCase().match(noPrefix))
- .sort((a, b) => {
- let aScore = 0
- let bScore = 0
+ .map(emoji => ({ ...emoji, ...nameKeywordLocalizer(emoji) }))
+ .filter((emoji) => (emoji.names.concat(emoji.keywords)).filter(kw => kw.toLowerCase().match(noPrefix)).length)
+ .map(k => {
+ let score = 0
// An exact match always wins
- aScore += a.displayText.toLowerCase() === noPrefix ? 200 : 0
- bScore += b.displayText.toLowerCase() === noPrefix ? 200 : 0
+ score += Math.max(...k.names.map(name => name.toLowerCase() === noPrefix ? 200 : 0), 0)
// Prioritize custom emoji a lot
- aScore += a.imageUrl ? 100 : 0
- bScore += b.imageUrl ? 100 : 0
+ score += k.imageUrl ? 100 : 0
// Prioritize prefix matches somewhat
- aScore += a.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0
- bScore += b.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0
+ score += Math.max(...k.names.map(kw => kw.toLowerCase().startsWith(noPrefix) ? 10 : 0), 0)
// Sort by length
- aScore -= a.displayText.length
- bScore -= b.displayText.length
+ score -= k.displayText.length
+ k.score = score
+ return k
+ })
+ .sort((a, b) => {
// Break ties alphabetically
const alphabetically = a.displayText > b.displayText ? 0.5 : -0.5
- return bScore - aScore + alphabetically
+ return b.score - a.score + alphabetically
})
}
--
cgit v1.2.3-70-g09d2