+
-
-
{{ $t("general.show_more") }}
-
-
-
{{ $t("general.show_more") }}
Date: Fri, 26 Jun 2020 14:47:02 +0300
Subject: [PATCH 14/41] add basic preloading for nodeinfo/config
---
src/boot/after_store.js | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 0db035475..0c213ea39 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -8,9 +8,34 @@ import backendInteractorService from '../services/backend_interactor_service/bac
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
import { applyTheme } from '../services/style_setter/style_setter.js'
+let staticInitialResults = null
+
+const parsedInitialResults = () => {
+ if (!document.getElementById('initial-results')) {
+ return null
+ }
+ if (!staticInitialResults) {
+ staticInitialResults = JSON.parse(document.getElementById('initial-results').textContent)
+ }
+ return staticInitialResults
+}
+
+const preloadFetch = async (request) => {
+ const data = parsedInitialResults()
+ if (!data || !data[request]) {
+ return window.fetch(request)
+ }
+ const requestJson = atob(data[request])
+ return {
+ ok: true,
+ json: () => JSON.parse(requestJson),
+ text: () => requestJson
+ }
+}
+
const getStatusnetConfig = async ({ store }) => {
try {
- const res = await window.fetch('/api/statusnet/config.json')
+ const res = await preloadFetch('/api/statusnet/config.json')
if (res.ok) {
const data = await res.json()
const { name, closed: registrationClosed, textlimit, uploadlimit, server, vapidPublicKey, safeDMMentionsEnabled } = data.site
@@ -132,7 +157,7 @@ const getTOS = async ({ store }) => {
const getInstancePanel = async ({ store }) => {
try {
- const res = await window.fetch('/instance/panel.html')
+ const res = await preloadFetch('/instance/panel.html')
if (res.ok) {
const html = await res.text()
store.dispatch('setInstanceOption', { name: 'instanceSpecificPanelContent', value: html })
@@ -195,7 +220,7 @@ const resolveStaffAccounts = ({ store, accounts }) => {
const getNodeInfo = async ({ store }) => {
try {
- const res = await window.fetch('/nodeinfo/2.0.json')
+ const res = await preloadFetch('/nodeinfo/2.0.json')
if (res.ok) {
const data = await res.json()
const metadata = data.metadata
From 8c3106c588f964a8e26c69784d5808ad1f72625c Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Fri, 26 Jun 2020 18:20:32 +0300
Subject: [PATCH 15/41] Change the show/hide strings about, remove subjected
status toggle when 'collapse' option not used
---
src/components/status_content/status_content.js | 4 ++--
src/components/status_content/status_content.vue | 10 ++++++----
src/i18n/en.json | 6 +++++-
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 66501b3eb..09ea3a208 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -48,10 +48,10 @@ const StatusContent = {
},
// When a status has a subject and is also tall, we should only have one show more/less button. If the default is to collapse statuses with subjects, we just treat it like a status with a subject; otherwise, we just treat it like a tall status.
mightHideBecauseSubject () {
- return this.status.summary && (!this.tallStatus || this.localCollapseSubjectDefault)
+ return !!this.status.summary && this.localCollapseSubjectDefault
},
mightHideBecauseTall () {
- return this.tallStatus && (!this.status.summary || !this.localCollapseSubjectDefault)
+ return this.tallStatus && !(this.status.summary && this.localCollapseSubjectDefault)
},
hideSubjectStatus () {
return this.mightHideBecauseSubject && !this.expandingSubject
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 5698b4c07..3460c2fa5 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -17,7 +17,7 @@
href="#"
class="tall-subject-hider"
@click.prevent="showingLongSubject=false"
- >{{ $t("general.show_less") }}
+ >{{ $t("status.hide_full_subject") }}
- {{ $t("general.show_more") }}
+ {{ $t("status.show_full_subject") }}
- {{ $t("general.show_more") }}
+ {{ $t("status.show_content") }}
{{ $t("general.show_less") }}
+ >
+ {{ tallStatus ? $t("general.show_less") : $t("status.hide_content") }}
+
diff --git a/src/i18n/en.json b/src/i18n/en.json
index eefe10e5e..ede8c3d8d 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -629,7 +629,11 @@
"status_unavailable": "Status unavailable",
"copy_link": "Copy link to status",
"thread_muted": "Thread muted",
- "thread_muted_and_words": ", has words:"
+ "thread_muted_and_words": ", has words:",
+ "show_full_subject": "Show full subject",
+ "hide_full_subject": "Hide full subject",
+ "show_content": "Show content",
+ "hide_content": "Hide content"
},
"user_card": {
"approve": "Approve",
From 4528b31256cc719c4f17ab5103af0d345ba5181a Mon Sep 17 00:00:00 2001
From: translate
Date: Sat, 27 Jun 2020 07:21:32 +0000
Subject: [PATCH 16/41] Translated using Weblate (Italian)
Currently translated at 72.7% (452 of 621 strings)
Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
---
src/i18n/it.json | 3 ++-
src/i18n/nl.json | 20 ++++++++++++++------
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/i18n/it.json b/src/i18n/it.json
index 6c8be351f..7311f0b69 100644
--- a/src/i18n/it.json
+++ b/src/i18n/it.json
@@ -255,7 +255,8 @@
"top_bar": "Barra superiore",
"panel_header": "Titolo pannello",
"badge_notification": "Notifica",
- "popover": "Suggerimenti, menù, sbalzi"
+ "popover": "Suggerimenti, menù, sbalzi",
+ "toggled": "Scambiato"
},
"common_colors": {
"rgbo": "Icone, accenti, medaglie",
diff --git a/src/i18n/nl.json b/src/i18n/nl.json
index af728b6eb..15ce5cbe4 100644
--- a/src/i18n/nl.json
+++ b/src/i18n/nl.json
@@ -28,7 +28,12 @@
"enable": "Inschakelen",
"confirm": "Bevestigen",
"verify": "Verifiëren",
- "generic_error": "Er is een fout opgetreden"
+ "generic_error": "Er is een fout opgetreden",
+ "peek": "Spiek",
+ "close": "Sluiten",
+ "retry": "Opnieuw proberen",
+ "error_retry": "Probeer het opnieuw",
+ "loading": "Laden…"
},
"login": {
"login": "Log in",
@@ -90,7 +95,7 @@
"text/bbcode": "BBCode"
},
"content_warning": "Onderwerp (optioneel)",
- "default": "Zojuist geland in L.A.",
+ "default": "Tijd voor anime!",
"direct_warning": "Deze post zal enkel zichtbaar zijn voor de personen die genoemd zijn.",
"posting": "Plaatsen",
"scope": {
@@ -377,7 +382,7 @@
"button": "Knop",
"text": "Nog een boel andere {0} en {1}",
"mono": "inhoud",
- "input": "Zojuist geland in L.A.",
+ "input": "Tijd voor anime!",
"faint_link": "handige gebruikershandleiding",
"fine_print": "Lees onze {0} om niets nuttig te leren!",
"header_faint": "Alles komt goed",
@@ -451,7 +456,7 @@
"user_mutes": "Gebruikers",
"useStreamingApi": "Berichten en meldingen in real-time ontvangen",
"useStreamingApiWarning": "(Afgeraden, experimenteel, kan berichten overslaan)",
- "type_domains_to_mute": "Voer domeinen in om te negeren",
+ "type_domains_to_mute": "Zoek domeinen om te negeren",
"upload_a_photo": "Upload een foto",
"fun": "Plezier",
"greentext": "Meme pijlen",
@@ -470,7 +475,8 @@
"frontend_version": "Frontend Versie",
"backend_version": "Backend Versie",
"title": "Versie"
- }
+ },
+ "mutes_and_blocks": "Negeringen en Blokkades"
},
"timeline": {
"collapse": "Inklappen",
@@ -708,7 +714,9 @@
"unpin": "Van profiel losmaken",
"delete": "Status verwijderen",
"repeats": "Herhalingen",
- "favorites": "Favorieten"
+ "favorites": "Favorieten",
+ "thread_muted_and_words": ", heeft woorden:",
+ "thread_muted": "Thread genegeerd"
},
"time": {
"years_short": "{0}j",
From 3113d904b921b1258c3709101d7e688767037079 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Sat, 27 Jun 2020 10:34:28 +0300
Subject: [PATCH 17/41] update changelog with profile fields
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index feabbf067..887588f32 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- 'Copy link' button for statuses (in the ellipsis menu)
- Autocomplete domains from list of known instances
- 'Bot' settings option and badge
+- Added profile meta data fields that can be set in profile settings
### Changed
- Registration page no longer requires email if the server is configured not to require it
From a8cb5e71d9ab3025786838d7123ad676a1e7fb66 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Sat, 27 Jun 2020 12:32:01 +0300
Subject: [PATCH 18/41] don't block ui with stickers or tos
---
src/boot/after_store.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 01074b8c3..de7c3ef4d 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -340,17 +340,18 @@ const afterStoreSetup = async ({ store, i18n }) => {
}
// Now we can try getting the server settings and logging in
+ // Most of these are preloaded into the index.html so blocking is minimized
await Promise.all([
checkOAuthToken({ store }),
- getTOS({ store }),
getInstancePanel({ store }),
- getStickers({ store }),
getNodeInfo({ store }),
getInstanceConfig({ store })
])
// Start fetching things that don't need to block the UI
store.dispatch('fetchMutes')
+ getTOS({ store })
+ getStickers({ store })
const router = new VueRouter({
mode: 'history',
From 46cf50a4d653b9f9b2b9d3f13d88a7af7b950d18 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Sat, 27 Jun 2020 12:59:24 +0300
Subject: [PATCH 19/41] rename variable requestJson when it's not actually json
---
src/boot/after_store.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index de7c3ef4d..1796eb1be 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -25,11 +25,11 @@ const preloadFetch = async (request) => {
if (!data || !data[request]) {
return window.fetch(request)
}
- const requestJson = atob(data[request])
+ const requestData = atob(data[request])
return {
ok: true,
- json: () => JSON.parse(requestJson),
- text: () => requestJson
+ json: () => JSON.parse(requestData),
+ text: () => requestData
}
}
From 195e83d0c8ab660a1dd6b29137295c2a6a36dca9 Mon Sep 17 00:00:00 2001
From: Fristi
Date: Sat, 27 Jun 2020 15:04:52 +0000
Subject: [PATCH 20/41] Translated using Weblate (Dutch)
Currently translated at 100.0% (626 of 626 strings)
Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/nl/
---
src/i18n/nl.json | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/i18n/nl.json b/src/i18n/nl.json
index 15ce5cbe4..bf270f87d 100644
--- a/src/i18n/nl.json
+++ b/src/i18n/nl.json
@@ -476,7 +476,14 @@
"backend_version": "Backend Versie",
"title": "Versie"
},
- "mutes_and_blocks": "Negeringen en Blokkades"
+ "mutes_and_blocks": "Negeringen en Blokkades",
+ "profile_fields": {
+ "value": "Inhoud",
+ "name": "Label",
+ "add_field": "Veld Toevoegen",
+ "label": "Profiel metadata"
+ },
+ "bot": "Dit is een bot account"
},
"timeline": {
"collapse": "Inklappen",
From 6529f9fa34c5e4e4786f76f63068d70c771d868e Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Tue, 30 Jun 2020 15:04:16 +0300
Subject: [PATCH 21/41] add strikethrough when parent isn't visible
---
src/components/status/status.vue | 11 ++++++++++-
.../entity_normalizer/entity_normalizer.service.js | 1 +
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 7ec29b288..c537358b5 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -208,7 +208,12 @@
@click.prevent="gotoOriginal(status.in_reply_to_status_id)"
>
- {{ $t('status.reply_to') }}
+
+ {{ $t('status.reply_to') }}
+
{
output.in_reply_to_screen_name = data.pleroma.in_reply_to_account_acct
output.thread_muted = pleroma.thread_muted
output.emoji_reactions = pleroma.emoji_reactions
+ output.parent_visible = pleroma.parent_visible === undefined ? true : pleroma.parent_visible
} else {
output.text = data.content
output.summary = data.spoiler_text
From ee1364a16770792e2a1040a0ea0b8f1693b5da52 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Tue, 30 Jun 2020 15:15:27 +0300
Subject: [PATCH 22/41] add no-statusId support for status popover
---
src/components/status/status.vue | 2 +-
src/components/status_popover/status_popover.js | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index c537358b5..8237be6c6 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -197,7 +197,7 @@
>
diff --git a/src/components/status_popover/status_popover.js b/src/components/status_popover/status_popover.js
index 159132a9e..51e7680c6 100644
--- a/src/components/status_popover/status_popover.js
+++ b/src/components/status_popover/status_popover.js
@@ -22,6 +22,10 @@ const StatusPopover = {
methods: {
enter () {
if (!this.status) {
+ if (!this.statusId) {
+ this.error = true
+ return
+ }
this.$store.dispatch('fetchStatus', this.statusId)
.then(data => (this.error = false))
.catch(e => (this.error = true))
From 3a79918b89fa41f8676e7f19862e6e29abd4ea14 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Tue, 30 Jun 2020 15:23:47 +0300
Subject: [PATCH 23/41] update changelog for reply-to strikethrough
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 887588f32..e98b27285 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Autocomplete domains from list of known instances
- 'Bot' settings option and badge
- Added profile meta data fields that can be set in profile settings
+- When a post is a reply to an unavailable post, the 'Reply to'-text has a strike-through style
### Changed
- Registration page no longer requires email if the server is configured not to require it
From ea09bbecf8b7715a1242a104b6233a7c3b5ac588 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Tue, 30 Jun 2020 17:02:38 +0300
Subject: [PATCH 24/41] Make use of backend reply filtering
---
CHANGELOG.md | 1 +
.../settings_modal/tabs/filtering_tab.js | 3 ++
src/components/status/status.js | 33 +------------------
src/components/timeline/timeline.js | 6 ++--
src/components/timeline/timeline.vue | 4 +--
src/modules/statuses.js | 8 +++++
src/services/api/api.service.js | 6 +++-
.../timeline_fetcher.service.js | 4 ++-
8 files changed, 27 insertions(+), 38 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 887588f32..d978d3624 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Subject field now appears disabled when posting
- Fix status ellipsis menu being cut off in notifications column
- Fixed autocomplete sometimes not returning the right user when there's already some results
+- Reply filtering options in Settings -> Filtering now work again using filtering on server
## [2.0.3] - 2020-05-02
### Fixed
diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js
index 224a7f479..3b2df5560 100644
--- a/src/components/settings_modal/tabs/filtering_tab.js
+++ b/src/components/settings_modal/tabs/filtering_tab.js
@@ -37,6 +37,9 @@ const FilteringTab = {
})
},
deep: true
+ },
+ replyVisibility () {
+ this.$store.dispatch('queueFlushAll')
}
}
}
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 733825212..ad0b72a9a 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -141,7 +141,7 @@ const Status = {
return this.mergedConfig.hideFilteredStatuses
},
hideStatus () {
- return (this.hideReply || this.deleted) || (this.muted && this.hideFilteredStatuses)
+ return this.deleted || (this.muted && this.hideFilteredStatuses)
},
isFocused () {
// retweet or root of an expanded conversation
@@ -164,37 +164,6 @@ const Status = {
return user && user.screen_name
}
},
- hideReply () {
- if (this.mergedConfig.replyVisibility === 'all') {
- return false
- }
- if (this.inConversation || !this.isReply) {
- return false
- }
- if (this.status.user.id === this.currentUser.id) {
- return false
- }
- if (this.status.type === 'retweet') {
- return false
- }
- const checkFollowing = this.mergedConfig.replyVisibility === 'following'
- for (var i = 0; i < this.status.attentions.length; ++i) {
- if (this.status.user.id === this.status.attentions[i].id) {
- continue
- }
- // There's zero guarantee of this working. If we happen to have that user and their
- // relationship in store then it will work, but there's kinda little chance of having
- // them for people you're not following.
- const relationship = this.$store.state.users.relationships[this.status.attentions[i].id]
- if (checkFollowing && relationship && relationship.following) {
- return false
- }
- if (this.status.attentions[i].id === this.currentUser.id) {
- return false
- }
- }
- return this.status.attentions.length > 0
- },
replySubject () {
if (!this.status.summary) return ''
const decodedSummary = unescape(this.status.summary)
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 9a53acd68..3a244c83b 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -45,6 +45,10 @@ const Timeline = {
newStatusCount () {
return this.timeline.newStatusCount
},
+ showLoadButton () {
+ if (this.timelineError || this.errorData) return false
+ return this.timeline.newStatusCount > 0 || this.timeline.flushMarker !== 0
+ },
newStatusCountStr () {
if (this.timeline.flushMarker !== 0) {
return ''
@@ -112,8 +116,6 @@ const Timeline = {
if (e.key === '.') this.showNewStatuses()
},
showNewStatuses () {
- if (this.newStatusCount === 0) return
-
if (this.timeline.flushMarker !== 0) {
this.$store.commit('clearTimeline', { timeline: this.timelineName, excludeUserId: true })
this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 })
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 9777bd0c3..bd8389b98 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -19,14 +19,14 @@
{{ errorData.statusText }}
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 073b15f1b..4d3f80314 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -515,6 +515,11 @@ export const mutations = {
queueFlush (state, { timeline, id }) {
state.timelines[timeline].flushMarker = id
},
+ queueFlushAll (state) {
+ Object.keys(state.timelines).forEach((timeline) => {
+ state.timelines[timeline].flushMarker = state.timelines[timeline].maxId
+ })
+ },
addRepeats (state, { id, rebloggedByUsers, currentUser }) {
const newStatus = state.allStatusesObject[id]
newStatus.rebloggedBy = rebloggedByUsers.filter(_ => _)
@@ -664,6 +669,9 @@ const statuses = {
queueFlush ({ rootState, commit }, { timeline, id }) {
commit('queueFlush', { timeline, id })
},
+ queueFlushAll ({ rootState, commit }) {
+ commit('queueFlushAll')
+ },
markNotificationsAsSeen ({ rootState, commit }) {
commit('markNotificationsAsSeen')
apiService.markNotificationsAsSeen({
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index dfffc291c..7e5e9645e 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -498,7 +498,8 @@ const fetchTimeline = ({
until = false,
userId = false,
tag = false,
- withMuted = false
+ withMuted = false,
+ replyVisibility = 'all'
}) => {
const timelineUrls = {
public: MASTODON_PUBLIC_TIMELINE,
@@ -541,6 +542,9 @@ const fetchTimeline = ({
if (timeline !== 'favorites') {
params.push(['with_muted', withMuted])
}
+ if (replyVisibility !== 'all') {
+ params.push(['reply_visibility', replyVisibility])
+ }
params.push(['limit', 20])
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index c6b28ad58..30fb26bdc 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -30,7 +30,8 @@ const fetchAndUpdate = ({
const rootState = store.rootState || store.state
const { getters } = store
const timelineData = rootState.statuses.timelines[camelCase(timeline)]
- const hideMutedPosts = getters.mergedConfig.hideMutedPosts
+ const { hideMutedPosts, replyVisibility } = getters.mergedConfig
+ const loggedIn = !!rootState.users.currentUser
if (older) {
args['until'] = until || timelineData.minId
@@ -41,6 +42,7 @@ const fetchAndUpdate = ({
args['userId'] = userId
args['tag'] = tag
args['withMuted'] = !hideMutedPosts
+ if (loggedIn) args['replyVisibility'] = replyVisibility
const numStatusesBeforeFetch = timelineData.statuses.length
From 38d8526660df4ca664c9ea50a660868be2cb5e49 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Tue, 30 Jun 2020 17:37:36 +0300
Subject: [PATCH 25/41] change Show New text to Reload when flushing
---
src/components/timeline/timeline.js | 6 +++---
src/components/timeline/timeline.vue | 2 +-
src/i18n/en.json | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 3a244c83b..d6519f4a2 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -49,11 +49,11 @@ const Timeline = {
if (this.timelineError || this.errorData) return false
return this.timeline.newStatusCount > 0 || this.timeline.flushMarker !== 0
},
- newStatusCountStr () {
+ loadButtonString () {
if (this.timeline.flushMarker !== 0) {
- return ''
+ return this.$t('timeline.reload')
} else {
- return ` (${this.newStatusCount})`
+ return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
}
},
classes () {
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index bd8389b98..111c0976b 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -23,7 +23,7 @@
class="loadmore-button"
@click.prevent="showNewStatuses"
>
- {{ $t('timeline.show_new') }}{{ newStatusCountStr }}
+ {{ loadButtonString }}
Date: Wed, 1 Jul 2020 14:15:04 +0300
Subject: [PATCH 26/41] remove unnecessary fetchAndUpdate, change notifications
fetcher to not double fetch
---
src/components/notifications/notifications.js | 5 -----
src/modules/api.js | 3 ---
.../backend_interactor_service.js | 4 ----
.../notifications_fetcher/notifications_fetcher.service.js | 7 +++++--
4 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index 26ffbab6c..e999a18e6 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -56,11 +56,6 @@ const Notifications = {
components: {
Notification
},
- created () {
- const { dispatch } = this.$store
-
- dispatch('fetchAndUpdateNotifications')
- },
watch: {
unseenCount (count) {
if (count > 0) {
diff --git a/src/modules/api.js b/src/modules/api.js
index 748570e56..04ef6ab42 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -138,9 +138,6 @@ const api = {
if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'notifications', fetcher })
},
- fetchAndUpdateNotifications (store) {
- store.state.backendInteractor.fetchAndUpdateNotifications({ store })
- },
// Follow requests
startFetchingFollowRequests (store) {
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index e1c32860d..45e6bd0e1 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -12,10 +12,6 @@ const backendInteractorService = credentials => ({
return notificationsFetcher.startFetching({ store, credentials })
},
- fetchAndUpdateNotifications ({ store }) {
- return notificationsFetcher.fetchAndUpdate({ store, credentials })
- },
-
startFetchingFollowRequests ({ store }) {
return followRequestFetcher.startFetching({ store, credentials })
},
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index 64499a1b6..581931f5b 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -31,8 +31,11 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
const notifications = timelineData.data
const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
if (readNotifsIds.length) {
- args['since'] = Math.max(...readNotifsIds)
- fetchNotifications({ store, args, older })
+ const possibleMax = Math.max(...readNotifsIds)
+ if (possibleMax !== timelineData.maxId) {
+ args['since'] = possibleMax
+ fetchNotifications({ store, args, older })
+ }
}
return result
From a3e370e9f816e3c98028bf82e8ac020b8e294466 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 15:19:45 +0300
Subject: [PATCH 27/41] add initial fetching back in a more streamlined way
---
src/components/notifications/notifications.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index e999a18e6..30187072d 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -27,6 +27,11 @@ const Notifications = {
seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT
}
},
+ created () {
+ const store = this.$store
+ const credentials = store.state.users.currentUser.credentials
+ notificationsFetcher.fetchAndUpdate({ store: this.$store, credentials })
+ },
computed: {
mainClass () {
return this.minimalMode ? '' : 'panel panel-default'
From ca997f45e8b2e6c8df72833d774bad7266af76bf Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 15:56:45 +0300
Subject: [PATCH 28/41] allow overscrolling enough to not have FAB block
interactables
---
src/App.scss | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/App.scss b/src/App.scss
index f2972eda5..6597b6f41 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -858,6 +858,10 @@ nav {
display: block;
margin-right: 0.8em;
}
+
+ .main {
+ margin-bottom: 7em;
+ }
}
.select-multiple {
From 3ebd4e4429a9680046daeac2ed8753471365be9e Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 17:55:42 +0300
Subject: [PATCH 29/41] document the 'mark-as-read-detection' system
---
.../notifications_fetcher.service.js | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index 581931f5b..c25524800 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -27,17 +27,18 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
}
const result = fetchNotifications({ store, args, older })
- // load unread notifications repeatedly to provide consistency between browser tabs
+ // If there's any unread notifications, try fetch notifications since
+ // the newest read notification to check if any of the unread notifs
+ // have changed their 'seen' state (marked as read in another session), so
+ // we can update the state in this session to mark them as read as well.
+ // The normal maxId-check does not tell if older notifications have changed
const notifications = timelineData.data
const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
- if (readNotifsIds.length) {
- const possibleMax = Math.max(...readNotifsIds)
- if (possibleMax !== timelineData.maxId) {
- args['since'] = possibleMax
- fetchNotifications({ store, args, older })
- }
+ const numUnseenNotifs = notifications.length - readNotifsIds.length
+ if (numUnseenNotifs > 0) {
+ args['since'] = Math.max(...readNotifsIds)
+ fetchNotifications({ store, args, older })
}
-
return result
}
}
From d30b0b28c9371e56ffe54b5a8b56087718221c1d Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 19:15:28 +0300
Subject: [PATCH 30/41] catch localforage error and let the application work,
add an alert for user to dismiss
---
src/App.js | 6 ++++++
src/App.scss | 9 +++++++++
src/App.vue | 10 ++++++++++
src/i18n/en.json | 3 +++
src/main.js | 13 +++++++++++--
src/modules/instance.js | 2 +-
src/modules/interface.js | 7 +++++++
7 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/src/App.js b/src/App.js
index 040138c97..da66fe214 100644
--- a/src/App.js
+++ b/src/App.js
@@ -107,6 +107,9 @@ export default {
return {
'order': this.$store.state.instance.sidebarRight ? 99 : 0
}
+ },
+ showStorageError () {
+ return this.$store.state.interface.storageError === 'show'
}
},
methods: {
@@ -129,6 +132,9 @@ export default {
if (changed) {
this.$store.dispatch('setMobileLayout', mobileLayout)
}
+ },
+ hideStorageError () {
+ this.$store.dispatch('setStorageError', 'hide')
}
}
}
diff --git a/src/App.scss b/src/App.scss
index f2972eda5..db447f1c3 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -806,6 +806,15 @@ nav {
}
}
+.storage-error-notice {
+ text-align: center;
+ i {
+ cursor: pointer;
+ color: $fallback--text;
+ color: var(--alertErrorText, $fallback--text);
+ }
+}
+
.button-icon {
font-size: 1.2em;
}
diff --git a/src/App.vue b/src/App.vue
index 7b9ad3dc1..23991eacc 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -101,6 +101,16 @@
+
+ {{ $t("errors.storage_unavailable") }}
+
+
{
- const persistedState = await createPersistedState(persistedStateOptions)
+ console.log('before perse state')
+ let persistedState
+ let storageError = 'none'
+ try {
+ persistedState = await createPersistedState(persistedStateOptions)
+ } catch (e) {
+ console.error(e)
+ storageError = 'show'
+ persistedState = _ => _
+ }
const store = new Vuex.Store({
modules: {
i18n: {
@@ -89,7 +98,7 @@ const persistedStateOptions = {
strict: false // Socket modifies itself, let's ignore this for now.
// strict: process.env.NODE_ENV !== 'production'
})
-
+ store.dispatch('setStorageError', storageError)
afterStoreSetup({ store, i18n })
})()
diff --git a/src/modules/instance.js b/src/modules/instance.js
index ec5f4e547..cc8843172 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -8,7 +8,7 @@ const defaultState = {
// Stuff from apiConfig
name: 'Pleroma FE',
registrationOpen: true,
- server: 'http://localhost:4040/',
+ server: 'http://lain.com:4040',
textlimit: 5000,
themeData: undefined,
vapidPublicKey: undefined,
diff --git a/src/modules/interface.js b/src/modules/interface.js
index eeebd65eb..4b5b5b5d9 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -8,6 +8,7 @@ const defaultState = {
noticeClearTimeout: null,
notificationPermission: null
},
+ storageError: 'none',
browserSupport: {
cssFilter: window.CSS && window.CSS.supports && (
window.CSS.supports('filter', 'drop-shadow(0 0)') ||
@@ -58,6 +59,9 @@ const interfaceMod = {
if (!state.settingsModalLoaded) {
state.settingsModalLoaded = true
}
+ },
+ setStorageError (state, value) {
+ state.storageError = value
}
},
actions: {
@@ -81,6 +85,9 @@ const interfaceMod = {
},
togglePeekSettingsModal ({ commit }) {
commit('togglePeekSettingsModal')
+ },
+ setStorageError ({ commit }, value) {
+ commit('setStorageError', value)
}
}
}
From 43b7a5d9b387e005a47debb5962c76c773cd862c Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 19:22:39 +0300
Subject: [PATCH 31/41] update the message and changelog
---
CHANGELOG.md | 1 +
src/i18n/en.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d978d3624..b57e9afb5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix status ellipsis menu being cut off in notifications column
- Fixed autocomplete sometimes not returning the right user when there's already some results
- Reply filtering options in Settings -> Filtering now work again using filtering on server
+- Don't show just blank-screen when cookies are disabled
## [2.0.3] - 2020-05-02
### Fixed
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 4856008f4..0b34ae074 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -164,7 +164,7 @@
"load_all": "Loading all {emojiAmount} emoji"
},
"errors": {
- "storage_unavailable": "Pleroma could not access browser storage. You may encounter issues and your login or your local settings won't be saved. Try enabling cookies."
+ "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."
},
"interactions": {
"favs_repeats": "Repeats and Favorites",
From 15d492ace4db5243330741a007daa9929e221f64 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 19:24:17 +0300
Subject: [PATCH 32/41] revert accidental change in instance.js
---
src/modules/instance.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/instance.js b/src/modules/instance.js
index cc8843172..ec5f4e547 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -8,7 +8,7 @@ const defaultState = {
// Stuff from apiConfig
name: 'Pleroma FE',
registrationOpen: true,
- server: 'http://lain.com:4040',
+ server: 'http://localhost:4040/',
textlimit: 5000,
themeData: undefined,
vapidPublicKey: undefined,
From 0997e5ff668a57d58002ec646f698c5503f66c35 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Wed, 1 Jul 2020 19:25:31 +0300
Subject: [PATCH 33/41] remove accidental log
---
src/main.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main.js b/src/main.js
index bb2c8cd36..a7294ea03 100644
--- a/src/main.js
+++ b/src/main.js
@@ -62,7 +62,6 @@ const persistedStateOptions = {
};
(async () => {
- console.log('before perse state')
let persistedState
let storageError = 'none'
try {
From 1293bec77e5137acf64d3536c286f8ba3df284f4 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Thu, 2 Jul 2020 10:40:41 +0300
Subject: [PATCH 34/41] change storage error one-off into a global notice
system
---
src/App.js | 10 +--
src/App.scss | 9 ---
src/App.vue | 11 +--
.../global_notice_list/global_notice_list.js | 15 ++++
.../global_notice_list/global_notice_list.vue | 77 +++++++++++++++++++
src/main.js | 16 ++--
src/modules/interface.js | 33 ++++++--
src/services/theme_data/pleromafe.js | 36 ++++++++-
8 files changed, 167 insertions(+), 40 deletions(-)
create mode 100644 src/components/global_notice_list/global_notice_list.js
create mode 100644 src/components/global_notice_list/global_notice_list.vue
diff --git a/src/App.js b/src/App.js
index da66fe214..92c4e2f58 100644
--- a/src/App.js
+++ b/src/App.js
@@ -13,6 +13,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil
import MobileNav from './components/mobile_nav/mobile_nav.vue'
import UserReportingModal from './components/user_reporting_modal/user_reporting_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 } from './services/window_utils/window_utils'
export default {
@@ -32,7 +33,8 @@ export default {
MobileNav,
SettingsModal,
UserReportingModal,
- PostStatusModal
+ PostStatusModal,
+ GlobalNoticeList
},
data: () => ({
mobileActivePanel: 'timeline',
@@ -107,9 +109,6 @@ export default {
return {
'order': this.$store.state.instance.sidebarRight ? 99 : 0
}
- },
- showStorageError () {
- return this.$store.state.interface.storageError === 'show'
}
},
methods: {
@@ -132,9 +131,6 @@ export default {
if (changed) {
this.$store.dispatch('setMobileLayout', mobileLayout)
}
- },
- hideStorageError () {
- this.$store.dispatch('setStorageError', 'hide')
}
}
}
diff --git a/src/App.scss b/src/App.scss
index db447f1c3..f2972eda5 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -806,15 +806,6 @@ nav {
}
}
-.storage-error-notice {
- text-align: center;
- i {
- cursor: pointer;
- color: $fallback--text;
- color: var(--alertErrorText, $fallback--text);
- }
-}
-
.button-icon {
font-size: 1.2em;
}
diff --git a/src/App.vue b/src/App.vue
index 23991eacc..03b632ecc 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -101,16 +101,6 @@
-
- {{ $t("errors.storage_unavailable") }}
-
-
+
diff --git a/src/components/global_notice_list/global_notice_list.js b/src/components/global_notice_list/global_notice_list.js
new file mode 100644
index 000000000..3af29c234
--- /dev/null
+++ b/src/components/global_notice_list/global_notice_list.js
@@ -0,0 +1,15 @@
+
+const GlobalNoticeList = {
+ computed: {
+ notices () {
+ return this.$store.state.interface.globalNotices
+ }
+ },
+ methods: {
+ closeNotice (notice) {
+ this.$store.dispatch('removeGlobalNotice', notice)
+ }
+ }
+}
+
+export default GlobalNoticeList
diff --git a/src/components/global_notice_list/global_notice_list.vue b/src/components/global_notice_list/global_notice_list.vue
new file mode 100644
index 000000000..0e4285ccf
--- /dev/null
+++ b/src/components/global_notice_list/global_notice_list.vue
@@ -0,0 +1,77 @@
+
+
+
+
+ {{ $t(notice.messageKey, notice.messageArgs) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
index a7294ea03..5bddc76e4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -62,14 +62,14 @@ const persistedStateOptions = {
};
(async () => {
- let persistedState
- let storageError = 'none'
+ let storageError = false
+ const plugins = [pushNotifications]
try {
- persistedState = await createPersistedState(persistedStateOptions)
+ const persistedState = await createPersistedState(persistedStateOptions)
+ plugins.push(persistedState)
} catch (e) {
console.error(e)
- storageError = 'show'
- persistedState = _ => _
+ storageError = true
}
const store = new Vuex.Store({
modules: {
@@ -93,11 +93,13 @@ const persistedStateOptions = {
polls: pollsModule,
postStatus: postStatusModule
},
- plugins: [persistedState, pushNotifications],
+ plugins,
strict: false // Socket modifies itself, let's ignore this for now.
// strict: process.env.NODE_ENV !== 'production'
})
- store.dispatch('setStorageError', storageError)
+ if (storageError) {
+ store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' })
+ }
afterStoreSetup({ store, i18n })
})()
diff --git a/src/modules/interface.js b/src/modules/interface.js
index 4b5b5b5d9..338ef6515 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -8,14 +8,14 @@ const defaultState = {
noticeClearTimeout: null,
notificationPermission: null
},
- storageError: 'none',
browserSupport: {
cssFilter: window.CSS && window.CSS.supports && (
window.CSS.supports('filter', 'drop-shadow(0 0)') ||
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
)
},
- mobileLayout: false
+ mobileLayout: false,
+ globalNotices: []
}
const interfaceMod = {
@@ -60,8 +60,11 @@ const interfaceMod = {
state.settingsModalLoaded = true
}
},
- setStorageError (state, value) {
- state.storageError = value
+ pushGlobalNotice (state, notice) {
+ state.globalNotices.push(notice)
+ },
+ removeGlobalNotice (state, notice) {
+ state.globalNotices = state.globalNotices.filter(n => n !== notice)
}
},
actions: {
@@ -86,8 +89,26 @@ const interfaceMod = {
togglePeekSettingsModal ({ commit }) {
commit('togglePeekSettingsModal')
},
- setStorageError ({ commit }, value) {
- commit('setStorageError', value)
+ pushGlobalNotice (
+ { commit, dispatch },
+ {
+ messageKey,
+ messageArgs = {},
+ level = 'error',
+ timeout = 0
+ }) {
+ const notice = {
+ messageKey,
+ messageArgs,
+ level
+ }
+ if (timeout) {
+ setTimeout(() => dispatch('removeGlobalNotice', notice), timeout)
+ }
+ commit('pushGlobalNotice', notice)
+ },
+ removeGlobalNotice ({ commit }, notice) {
+ commit('removeGlobalNotice', notice)
}
}
}
diff --git a/src/services/theme_data/pleromafe.js b/src/services/theme_data/pleromafe.js
index b577cfab8..83c878ed9 100644
--- a/src/services/theme_data/pleromafe.js
+++ b/src/services/theme_data/pleromafe.js
@@ -34,7 +34,8 @@ export const DEFAULT_OPACITY = {
alert: 0.5,
input: 0.5,
faint: 0.5,
- underlay: 0.15
+ underlay: 0.15,
+ alertPopup: 0.85
}
/** SUBJECT TO CHANGE IN THE FUTURE, this is all beta
@@ -627,6 +628,39 @@ export const SLOT_INHERITANCE = {
textColor: true
},
+ alertPopupError: {
+ depends: ['alertError'],
+ opacity: 'alertPopup'
+ },
+ alertPopupErrorText: {
+ depends: ['alertErrorText'],
+ layer: 'popover',
+ variant: 'alertPopupError',
+ textColor: true
+ },
+
+ alertPopupWarning: {
+ depends: ['alertWarning'],
+ opacity: 'alertPopup'
+ },
+ alertPopupWarningText: {
+ depends: ['alertWarningText'],
+ layer: 'popover',
+ variant: 'alertPopupWarning',
+ textColor: true
+ },
+
+ alertPopupNeutral: {
+ depends: ['alertNeutral'],
+ opacity: 'alertPopup'
+ },
+ alertPopupNeutralText: {
+ depends: ['alertNeutralText'],
+ layer: 'popover',
+ variant: 'alertPopupNeutral',
+ textColor: true
+ },
+
badgeNotification: '--cRed',
badgeNotificationText: {
depends: ['text', 'badgeNotification'],
From 685ab4f33ee57e1dc4997b58314e5c0d38581e9d Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Thu, 2 Jul 2020 10:46:43 +0300
Subject: [PATCH 35/41] make the addNotice dispatch return the notice
---
src/modules/interface.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/modules/interface.js b/src/modules/interface.js
index 338ef6515..e31630fcb 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -106,6 +106,7 @@ const interfaceMod = {
setTimeout(() => dispatch('removeGlobalNotice', notice), timeout)
}
commit('pushGlobalNotice', notice)
+ return notice
},
removeGlobalNotice ({ commit }, notice) {
commit('removeGlobalNotice', notice)
From f0668c9ff8b985cd5f537fbb0d1083480cbfb065 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Thu, 2 Jul 2020 12:19:33 +0300
Subject: [PATCH 36/41] add follow request users to store
---
.../follow_request_fetcher/follow_request_fetcher.service.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/services/follow_request_fetcher/follow_request_fetcher.service.js b/src/services/follow_request_fetcher/follow_request_fetcher.service.js
index 786740b7e..93fac9bc0 100644
--- a/src/services/follow_request_fetcher/follow_request_fetcher.service.js
+++ b/src/services/follow_request_fetcher/follow_request_fetcher.service.js
@@ -4,6 +4,7 @@ const fetchAndUpdate = ({ store, credentials }) => {
return apiService.fetchFollowRequests({ credentials })
.then((requests) => {
store.commit('setFollowRequests', requests)
+ store.commit('addNewUsers', requests)
}, () => {})
.catch(() => {})
}
From 9cac5d94dd78ea331254307871e876da7e266a6f Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson
Date: Thu, 2 Jul 2020 15:17:58 +0300
Subject: [PATCH 37/41] change alert popup alpha
---
src/services/theme_data/pleromafe.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/services/theme_data/pleromafe.js b/src/services/theme_data/pleromafe.js
index 83c878ed9..6b25cd6f6 100644
--- a/src/services/theme_data/pleromafe.js
+++ b/src/services/theme_data/pleromafe.js
@@ -35,7 +35,7 @@ export const DEFAULT_OPACITY = {
input: 0.5,
faint: 0.5,
underlay: 0.15,
- alertPopup: 0.85
+ alertPopup: 0.95
}
/** SUBJECT TO CHANGE IN THE FUTURE, this is all beta
From 08b593746faf54ac41df25bb2cc5a1f72ae1a9b5 Mon Sep 17 00:00:00 2001
From: Ilja
Date: Fri, 3 Jul 2020 10:17:42 +0000
Subject: [PATCH 38/41] FE part of BE issue 1586 provide index md
* I added an index.md which will be the landing page for the docs. It has an explanation of Pleroma-FE from the user point of view
* See also BE MR: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/2669
* And issue: https://git.pleroma.social/pleroma/pleroma/-/issues/1586
---
docs/USER_GUIDE.md | 2 --
docs/index.md | 8 ++++++++
2 files changed, 8 insertions(+), 2 deletions(-)
create mode 100644 docs/index.md
diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md
index f417f33d7..241ad331b 100644
--- a/docs/USER_GUIDE.md
+++ b/docs/USER_GUIDE.md
@@ -8,8 +8,6 @@
>
> --Catbag
-Pleroma-FE user interface is modeled after Qvitter which is modeled after older Twitter design. It provides a simple 2-column interface for microblogging. While being simple by default it also provides many powerful customization options.
-
## Posting, reading, basic functions.
After registering and logging in you're presented with your timeline in right column and new post form with timeline list and notifications in the left column.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 000000000..8764f9ab2
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,8 @@
+# Introduction to Pleroma-FE
+## What is Pleroma-FE?
+
+Pleroma-FE is the default user-facing frontend for Pleroma. It's user interface is modeled after Qvitter which is modeled after an older Twitter design. It provides a simple 2-column interface for microblogging. While being simple by default it also provides many powerful customization options.
+
+## How can I use it?
+
+If your instance uses Pleroma-FE, you can acces it by going to your instance (e.g. ). You can read more about it's basic functionality in the [Pleroma-FE User Guide](./USER_GUIDE.md). We also have [a guide for administrators](./CONFIGURATION.md) and for [hackers/contributors](./HACKING.md).
From de291e2e33f1d9e04b27ed30ba3b012d73178e63 Mon Sep 17 00:00:00 2001
From: Eugenij
Date: Fri, 3 Jul 2020 19:45:49 +0000
Subject: [PATCH 39/41] Add bookmarks
Co-authored-by: jared
---
CHANGELOG.md | 1 +
package.json | 1 +
src/boot/routes.js | 2 +
.../bookmark_timeline/bookmark_timeline.js | 17 ++++++++
.../bookmark_timeline/bookmark_timeline.vue | 9 ++++
src/components/extra_buttons/extra_buttons.js | 10 +++++
.../extra_buttons/extra_buttons.vue | 16 +++++++
src/components/nav_panel/nav_panel.vue | 5 +++
src/components/side_drawer/side_drawer.vue | 8 ++++
src/components/timeline/timeline.js | 2 +-
src/i18n/en.json | 6 ++-
src/i18n/ru.json | 7 ++-
src/modules/statuses.js | 43 +++++++++++++++----
src/services/api/api.service.js | 34 +++++++++++++--
.../entity_normalizer.service.js | 16 +++++++
.../notifications_fetcher.service.js | 2 +-
.../timeline_fetcher.service.js | 17 +++++---
static/fontello.json | 12 ++++++
.../entity_normalizer.spec.js | 22 +++++++++-
yarn.lock | 7 +++
20 files changed, 213 insertions(+), 24 deletions(-)
create mode 100644 src/components/bookmark_timeline/bookmark_timeline.js
create mode 100644 src/components/bookmark_timeline/bookmark_timeline.vue
mode change 100755 => 100644 static/fontello.json
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d978d3624..2595af1d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -99,6 +99,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Ability to change user's email
- About page
- Added remote user redirect
+- Bookmarks
### Changed
- changed the way fading effects for user profile/long statuses works, now uses css-mask instead of gradient background hacks which weren't exactly compatible with semi-transparent themes
### Fixed
diff --git a/package.json b/package.json
index c0665f6eb..962311719 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"cropperjs": "^1.4.3",
"diff": "^3.0.1",
"escape-html": "^1.0.3",
+ "parse-link-header": "^1.0.1",
"localforage": "^1.5.0",
"phoenix": "^1.3.0",
"portal-vue": "^2.1.4",
diff --git a/src/boot/routes.js b/src/boot/routes.js
index d98a3b503..f63d8adfa 100644
--- a/src/boot/routes.js
+++ b/src/boot/routes.js
@@ -2,6 +2,7 @@ import PublicTimeline from 'components/public_timeline/public_timeline.vue'
import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue'
import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue'
import TagTimeline from 'components/tag_timeline/tag_timeline.vue'
+import BookmarkTimeline from 'components/bookmark_timeline/bookmark_timeline.vue'
import ConversationPage from 'components/conversation-page/conversation-page.vue'
import Interactions from 'components/interactions/interactions.vue'
import DMs from 'components/dm_timeline/dm_timeline.vue'
@@ -40,6 +41,7 @@ export default (store) => {
{ name: 'public-timeline', path: '/main/public', component: PublicTimeline },
{ name: 'friends', path: '/main/friends', component: FriendsTimeline, beforeEnter: validateAuthenticatedRoute },
{ name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
+ { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
{ name: 'remote-user-profile-acct',
path: '/remote-users/(@?):username([^/@]+)@:hostname([^/@]+)',
diff --git a/src/components/bookmark_timeline/bookmark_timeline.js b/src/components/bookmark_timeline/bookmark_timeline.js
new file mode 100644
index 000000000..64b69e5d1
--- /dev/null
+++ b/src/components/bookmark_timeline/bookmark_timeline.js
@@ -0,0 +1,17 @@
+import Timeline from '../timeline/timeline.vue'
+
+const Bookmarks = {
+ computed: {
+ timeline () {
+ return this.$store.state.statuses.timelines.bookmarks
+ }
+ },
+ components: {
+ Timeline
+ },
+ destroyed () {
+ this.$store.commit('clearTimeline', { timeline: 'bookmarks' })
+ }
+}
+
+export default Bookmarks
diff --git a/src/components/bookmark_timeline/bookmark_timeline.vue b/src/components/bookmark_timeline/bookmark_timeline.vue
new file mode 100644
index 000000000..8da6884b8
--- /dev/null
+++ b/src/components/bookmark_timeline/bookmark_timeline.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index e4b19d010..5e0c36bb3 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -34,6 +34,16 @@ const ExtraButtons = {
navigator.clipboard.writeText(this.statusLink)
.then(() => this.$emit('onSuccess'))
.catch(err => this.$emit('onError', err.error.error))
+ },
+ bookmarkStatus () {
+ this.$store.dispatch('bookmark', { id: this.status.id })
+ .then(() => this.$emit('onSuccess'))
+ .catch(err => this.$emit('onError', err.error.error))
+ },
+ unbookmarkStatus () {
+ this.$store.dispatch('unbookmark', { id: this.status.id })
+ .then(() => this.$emit('onSuccess'))
+ .catch(err => this.$emit('onError', err.error.error))
}
},
computed: {
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 68db6fd8f..7a4e8642f 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -40,6 +40,22 @@
>
{{ $t("status.unpin") }}
+
+
{{ $t("nav.dms") }}
+
+
+ {{ $t("nav.bookmarks") }}
+
+
{{ $t("nav.friend_requests") }}
diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue
index f253742d1..0ac53b347 100644
--- a/src/components/side_drawer/side_drawer.vue
+++ b/src/components/side_drawer/side_drawer.vue
@@ -65,6 +65,14 @@
{{ $t("nav.timeline") }}
+
+
+ {{ $t("nav.bookmarks") }}
+
+
{
+ }).then(({ statuses }) => {
store.commit('setLoading', { timeline: this.timelineName, value: false })
if (statuses && statuses.length === 0) {
this.bottomedOut = true
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 59f69e576..2e48c4738 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -120,6 +120,7 @@
"public_tl": "Public Timeline",
"timeline": "Timeline",
"twkn": "The Whole Known Network",
+ "bookmarks": "Bookmarks",
"user_search": "User Search",
"search": "Search",
"who_to_follow": "Who to follow",
@@ -629,6 +630,8 @@
"pin": "Pin on profile",
"unpin": "Unpin from profile",
"pinned": "Pinned",
+ "bookmark": "Bookmark",
+ "unbookmark": "Unbookmark",
"delete_confirm": "Do you really want to delete this status?",
"reply_to": "Reply to",
"replies_list": "Replies:",
@@ -724,7 +727,8 @@
"add_reaction": "Add Reaction",
"user_settings": "User Settings",
"accept_follow_request": "Accept follow request",
- "reject_follow_request": "Reject follow request"
+ "reject_follow_request": "Reject follow request",
+ "bookmark": "Bookmark"
},
"upload": {
"error": {
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index aa78db26e..08f05d18e 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -45,7 +45,8 @@
"timeline": "Лента",
"twkn": "Федеративная лента",
"search": "Поиск",
- "friend_requests": "Запросы на чтение"
+ "friend_requests": "Запросы на чтение",
+ "bookmarks": "Закладки"
},
"notifications": {
"broken_favorite": "Неизвестный статус, ищем...",
@@ -366,6 +367,10 @@
"show_new": "Показать новые",
"up_to_date": "Обновлено"
},
+ "status": {
+ "bookmark": "В закладки",
+ "unbookmark": "Удалить из закладок"
+ },
"user_card": {
"block": "Заблокировать",
"blocked": "Заблокирован",
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 4d3f80314..7fbf685cf 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -62,7 +62,8 @@ export const defaultState = () => ({
publicAndExternal: emptyTl(),
friends: emptyTl(),
tag: emptyTl(),
- dms: emptyTl()
+ dms: emptyTl(),
+ bookmarks: emptyTl()
}
})
@@ -163,8 +164,7 @@ const removeStatusFromGlobalStorage = (state, status) => {
}
}
-const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {},
- noIdUpdate = false, userId }) => {
+const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {}, noIdUpdate = false, userId, pagination = {} }) => {
// Sanity check
if (!isArray(statuses)) {
return false
@@ -173,8 +173,13 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
const allStatuses = state.allStatuses
const timelineObject = state.timelines[timeline]
- const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
- const minNew = statuses.length > 0 ? minBy(statuses, 'id').id : 0
+ // Mismatch between API pagination and our internal minId/maxId tracking systems:
+ // pagination.maxId is the oldest of the returned statuses when fetching older,
+ // and pagination.minId is the newest when fetching newer. The names come directly
+ // from the arguments they're supposed to be passed as for the next fetch.
+ const minNew = pagination.maxId || (statuses.length > 0 ? minBy(statuses, 'id').id : 0)
+ const maxNew = pagination.minId || (statuses.length > 0 ? maxBy(statuses, 'id').id : 0)
+
const newer = timeline && (maxNew > timelineObject.maxId || timelineObject.maxId === 0) && statuses.length > 0
const older = timeline && (minNew < timelineObject.minId || timelineObject.minId === 0) && statuses.length > 0
@@ -315,7 +320,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
})
// Keep the visible statuses sorted
- if (timeline) {
+ if (timeline && !(timeline === 'bookmarks')) {
sortTimeline(timelineObject)
}
}
@@ -463,6 +468,14 @@ export const mutations = {
newStatus.rebloggedBy.push(user)
}
},
+ setBookmarked (state, { status, value }) {
+ const newStatus = state.allStatusesObject[status.id]
+ newStatus.bookmarked = value
+ },
+ setBookmarkedConfirm (state, { status }) {
+ const newStatus = state.allStatusesObject[status.id]
+ newStatus.bookmarked = status.bookmarked
+ },
setDeleted (state, { status }) {
const newStatus = state.allStatusesObject[status.id]
newStatus.deleted = true
@@ -590,8 +603,8 @@ export const mutations = {
const statuses = {
state: defaultState(),
actions: {
- addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId }) {
- commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId })
+ addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId, pagination }) {
+ commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId, pagination })
},
addNewNotifications ({ rootState, commit, dispatch, rootGetters }, { notifications, older }) {
commit('addNewNotifications', { visibleNotificationTypes: visibleNotificationTypes(rootState), dispatch, notifications, older, rootGetters })
@@ -666,6 +679,20 @@ const statuses = {
rootState.api.backendInteractor.unretweet({ id: status.id })
.then(status => commit('setRetweetedConfirm', { status, user: rootState.users.currentUser }))
},
+ bookmark ({ rootState, commit }, status) {
+ commit('setBookmarked', { status, value: true })
+ rootState.api.backendInteractor.bookmarkStatus({ id: status.id })
+ .then(status => {
+ commit('setBookmarkedConfirm', { status })
+ })
+ },
+ unbookmark ({ rootState, commit }, status) {
+ commit('setBookmarked', { status, value: false })
+ rootState.api.backendInteractor.unbookmarkStatus({ id: status.id })
+ .then(status => {
+ commit('setBookmarkedConfirm', { status })
+ })
+ },
queueFlush ({ rootState, commit }, { timeline, id }) {
commit('queueFlush', { timeline, id })
},
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 7e5e9645e..c9ec88b76 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -1,5 +1,5 @@
import { each, map, concat, last, get } from 'lodash'
-import { parseStatus, parseUser, parseNotification, parseAttachment } from '../entity_normalizer/entity_normalizer.service.js'
+import { parseStatus, parseUser, parseNotification, parseAttachment, parseLinkHeaderPagination } from '../entity_normalizer/entity_normalizer.service.js'
import { RegistrationError, StatusCodeError } from '../errors/errors'
/* eslint-env browser */
@@ -50,6 +50,7 @@ const MASTODON_USER_URL = '/api/v1/accounts'
const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses`
const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}`
+const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks'
const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/'
const MASTODON_USER_MUTES_URL = '/api/v1/mutes/'
const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block`
@@ -58,6 +59,8 @@ const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute`
const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute`
const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe`
const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe`
+const MASTODON_BOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/bookmark`
+const MASTODON_UNBOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/unbookmark`
const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media'
const MASTODON_VOTE_URL = id => `/api/v1/polls/${id}/votes`
@@ -510,7 +513,8 @@ const fetchTimeline = ({
user: MASTODON_USER_TIMELINE_URL,
media: MASTODON_USER_TIMELINE_URL,
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
- tag: MASTODON_TAG_TIMELINE_URL
+ tag: MASTODON_TAG_TIMELINE_URL,
+ bookmarks: MASTODON_BOOKMARK_TIMELINE_URL
}
const isNotifications = timeline === 'notifications'
const params = []
@@ -539,7 +543,7 @@ const fetchTimeline = ({
if (timeline === 'public' || timeline === 'publicAndExternal') {
params.push(['only_media', false])
}
- if (timeline !== 'favorites') {
+ if (timeline !== 'favorites' && timeline !== 'bookmarks') {
params.push(['with_muted', withMuted])
}
if (replyVisibility !== 'all') {
@@ -552,16 +556,20 @@ const fetchTimeline = ({
url += `?${queryString}`
let status = ''
let statusText = ''
+ let pagination = {}
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => {
status = data.status
statusText = data.statusText
+ pagination = parseLinkHeaderPagination(data.headers.get('Link'), {
+ flakeId: timeline !== 'bookmarks' && timeline !== 'notifications'
+ })
return data
})
.then((data) => data.json())
.then((data) => {
if (!data.error) {
- return data.map(isNotifications ? parseNotification : parseStatus)
+ return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination }
} else {
data.status = status
data.statusText = statusText
@@ -612,6 +620,22 @@ const unretweet = ({ id, credentials }) => {
.then((data) => parseStatus(data))
}
+const bookmarkStatus = ({ id, credentials }) => {
+ return promisedRequest({
+ url: MASTODON_BOOKMARK_STATUS_URL(id),
+ headers: authHeaders(credentials),
+ method: 'POST'
+ })
+}
+
+const unbookmarkStatus = ({ id, credentials }) => {
+ return promisedRequest({
+ url: MASTODON_UNBOOKMARK_STATUS_URL(id),
+ headers: authHeaders(credentials),
+ method: 'POST'
+ })
+}
+
const postStatus = ({
credentials,
status,
@@ -1150,6 +1174,8 @@ const apiService = {
unfavorite,
retweet,
unretweet,
+ bookmarkStatus,
+ unbookmarkStatus,
postStatus,
deleteStatus,
uploadMedia,
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 3bdb92f3f..0d27dc972 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -1,4 +1,5 @@
import escape from 'escape-html'
+import parseLinkHeader from 'parse-link-header'
import { isStatusNotification } from '../notification_utils/notification_utils.js'
const qvitterStatusType = (status) => {
@@ -232,6 +233,8 @@ export const parseStatus = (data) => {
output.repeated = data.reblogged
output.repeat_num = data.reblogs_count
+ output.bookmarked = data.bookmarked
+
output.type = data.reblog ? 'retweet' : 'status'
output.nsfw = data.sensitive
@@ -381,3 +384,16 @@ const isNsfw = (status) => {
const nsfwRegex = /#nsfw/i
return (status.tags || []).includes('nsfw') || !!(status.text || '').match(nsfwRegex)
}
+
+export const parseLinkHeaderPagination = (linkHeader, opts = {}) => {
+ const flakeId = opts.flakeId
+ const parsedLinkHeader = parseLinkHeader(linkHeader)
+ if (!parsedLinkHeader) return
+ const maxId = parsedLinkHeader.next.max_id
+ const minId = parsedLinkHeader.prev.min_id
+
+ return {
+ maxId: flakeId ? maxId : parseInt(maxId, 10),
+ minId: flakeId ? minId : parseInt(minId, 10)
+ }
+}
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index 64499a1b6..4644e4493 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -41,7 +41,7 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
const fetchNotifications = ({ store, args, older }) => {
return apiService.fetchTimeline(args)
- .then((notifications) => {
+ .then(({ data: notifications }) => {
update({ store, notifications, older })
return notifications
}, () => store.dispatch('setNotificationsError', { value: true }))
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index 30fb26bdc..214294eb5 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -2,7 +2,7 @@ import { camelCase } from 'lodash'
import apiService from '../api/api.service.js'
-const update = ({ store, statuses, timeline, showImmediately, userId }) => {
+const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => {
const ccTimeline = camelCase(timeline)
store.dispatch('setError', { value: false })
@@ -12,7 +12,8 @@ const update = ({ store, statuses, timeline, showImmediately, userId }) => {
timeline: ccTimeline,
userId,
statuses,
- showImmediately
+ showImmediately,
+ pagination
})
}
@@ -47,16 +48,18 @@ const fetchAndUpdate = ({
const numStatusesBeforeFetch = timelineData.statuses.length
return apiService.fetchTimeline(args)
- .then((statuses) => {
- if (statuses.error) {
- store.dispatch('setErrorData', { value: statuses })
+ .then(response => {
+ if (response.error) {
+ store.dispatch('setErrorData', { value: response })
return
}
+
+ const { data: statuses, pagination } = response
if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) {
store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId })
}
- update({ store, statuses, timeline, showImmediately, userId })
- return statuses
+ update({ store, statuses, timeline, showImmediately, userId, pagination })
+ return { statuses, pagination }
}, () => store.dispatch('setError', { value: true }))
}
diff --git a/static/fontello.json b/static/fontello.json
old mode 100755
new mode 100644
index ac3f0a18c..6083c0bfa
--- a/static/fontello.json
+++ b/static/fontello.json
@@ -375,6 +375,18 @@
"css": "download",
"code": 59429,
"src": "fontawesome"
+ },
+ {
+ "uid": "f04a5d24e9e659145b966739c4fde82a",
+ "css": "bookmark",
+ "code": 59430,
+ "src": "fontawesome"
+ },
+ {
+ "uid": "2f5ef6f6b7aaebc56458ab4e865beff5",
+ "css": "bookmark-empty",
+ "code": 61591,
+ "src": "fontawesome"
}
]
}
\ No newline at end of file
diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
index ccb57942c..e1f7a958f 100644
--- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -1,4 +1,4 @@
-import { parseStatus, parseUser, parseNotification, addEmojis } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
+import { parseStatus, parseUser, parseNotification, addEmojis, parseLinkHeaderPagination } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
import mastoapidata from '../../../../fixtures/mastoapi.json'
import qvitterapidata from '../../../../fixtures/statuses.json'
@@ -383,4 +383,24 @@ describe('API Entities normalizer', () => {
expect(result).to.include('title=\':[a-z] {|}*:\'')
})
})
+
+ describe('Link header pagination', () => {
+ it('Parses min and max ids as integers', () => {
+ const linkHeader = '; rel="next", ; rel="prev"'
+ const result = parseLinkHeaderPagination(linkHeader)
+ expect(result).to.eql({
+ 'maxId': 861676,
+ 'minId': 861741
+ })
+ })
+
+ it('Parses min and max ids as flakes', () => {
+ const linkHeader = '; rel="next", ; rel="prev"'
+ const result = parseLinkHeaderPagination(linkHeader, { flakeId: true })
+ expect(result).to.eql({
+ 'maxId': '9waQx5IIS48qVue2Ai',
+ 'minId': '9wi61nIPnfn674xgie'
+ })
+ })
+ })
})
diff --git a/yarn.lock b/yarn.lock
index f05b00b15..093168631 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5751,6 +5751,13 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
+parse-link-header@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parse-link-header/-/parse-link-header-1.0.1.tgz#bedfe0d2118aeb84be75e7b025419ec8a61140a7"
+ integrity sha1-vt/g0hGK64S+deewJUGeyKYRQKc=
+ dependencies:
+ xtend "~4.0.1"
+
parseqs@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d"
From 9b40cf43d80f61d2afdaed757e4f873bf2dfd0a4 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Sat, 4 Jul 2020 18:42:15 +0900
Subject: [PATCH 40/41] fix height for emoji panel of settings modal
---
src/components/settings_modal/settings_modal.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss
index 833ff89a5..0da4d9a85 100644
--- a/src/components/settings_modal/settings_modal.scss
+++ b/src/components/settings_modal/settings_modal.scss
@@ -30,7 +30,7 @@
height: 100vh;
}
- .panel-body {
+ >.panel-body {
height: 100%;
overflow-y: hidden;
From 9178908c1ea8d0ad99b4a631abb9594edc3765bf Mon Sep 17 00:00:00 2001
From: Shpuld Shpludson
Date: Sun, 5 Jul 2020 06:54:12 +0000
Subject: [PATCH 41/41] Apply suggestion to
src/components/notifications/notifications.js
---
src/components/notifications/notifications.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index 30187072d..d8a327b05 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -30,7 +30,7 @@ const Notifications = {
created () {
const store = this.$store
const credentials = store.state.users.currentUser.credentials
- notificationsFetcher.fetchAndUpdate({ store: this.$store, credentials })
+ notificationsFetcher.fetchAndUpdate({ store, credentials })
},
computed: {
mainClass () {