From ca4d5950d08aec6fe016b56f7125f7328c1e19a1 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Sat, 16 Nov 2019 03:12:16 +0900
Subject: [PATCH 01/52] Display user profile fields
---
src/components/user_profile/user_profile.js | 8 ++++
src/components/user_profile/user_profile.vue | 50 ++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 00055707..c5ab5f26 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -123,6 +123,14 @@ const UserProfile = {
onTabSwitch (tab) {
this.tab = tab
this.$router.replace({ query: { tab } })
+ },
+ linkClicked ({ target }) {
+ if (target.tagName === 'SPAN') {
+ target = target.parentNode
+ }
+ if (target.tagName === 'A') {
+ window.open(target.href, '_blank')
+ }
}
},
watch: {
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 14082e83..f979eff4 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -11,6 +11,44 @@
:allow-zooming-avatar="true"
rounded="top"
/>
+
+
+
+ -
+ {{ field.name }}
+
+ -
+ {{ field.value }}
+
+
+
Date: Mon, 18 Nov 2019 00:27:14 +0900
Subject: [PATCH 02/52] Fix emoji size
---
src/components/user_profile/user_profile.vue | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index f979eff4..d5aa514e 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -152,6 +152,18 @@
flex-basis: 500px;
.user-profile-fields {
+ img {
+ object-fit: contain;
+ vertical-align: middle;
+ max-width: 100%;
+ max-height: 400px;
+
+ &.emoji {
+ width: 32px;
+ height: 32px;
+ }
+ }
+
dl {
margin: 1em 1.5em;
From 004827a7f17a0bc349baf1257aa5debe3c6f6060 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Mon, 18 Nov 2019 02:16:37 +0900
Subject: [PATCH 03/52] Change profile fields design to horizontal
---
src/components/user_profile/user_profile.vue | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index d5aa514e..fdff0385 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -159,15 +159,31 @@
max-height: 400px;
&.emoji {
- width: 32px;
- height: 32px;
+ width: 18px;
+ height: 18px;
}
}
dl {
+ display: flex;
margin: 1em 1.5em;
+ dt {
+ flex: 0 0 auto;
+ font-weight: 500;
+ color: var(--lightText);
+ width: 30%;
+ min-width: 120px;
+ }
+
+ dd {
+ flex: 1 1 auto;
+ color: var(--text);
+ margin-left: 10px;
+ }
+
dt, dd {
+ line-height: 18px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
From 87940ead8a9bedd312f10635462933a02e0ffb1c Mon Sep 17 00:00:00 2001
From: kPherox
Date: Wed, 20 Nov 2019 18:59:37 +0900
Subject: [PATCH 04/52] Change css selectors to classname from elementname
---
src/components/user_profile/user_profile.vue | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index fdff0385..c1337411 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -18,6 +18,7 @@
-
Date: Wed, 20 Nov 2019 19:18:19 +0900
Subject: [PATCH 05/52] Add tooltip
---
src/components/user_profile/user_profile.vue | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index c1337411..20a64409 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -22,11 +22,13 @@
>
-
Date: Wed, 20 Nov 2019 19:22:20 +0900
Subject: [PATCH 06/52] Use fields_html only
---
src/components/user_profile/user_profile.vue | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 20a64409..0268e5da 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -36,22 +36,6 @@
-
-
- -
- {{ field.name }}
-
- -
- {{ field.value }}
-
-
-
Date: Wed, 20 Nov 2019 19:25:11 +0900
Subject: [PATCH 07/52] Change field name to right justify
---
src/components/user_profile/user_profile.vue | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 0268e5da..5bffba3a 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -158,6 +158,7 @@
.user-profile-field-name {
flex: 0 0 auto;
font-weight: 500;
+ text-align: right;
color: var(--lightText);
width: 30%;
min-width: 120px;
From da55b0d4352d2daf4a8d9f4130d34546e9f01555 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Wed, 19 Feb 2020 20:57:58 +0900
Subject: [PATCH 08/52] Add fields_text for tooltip
---
.../entity_normalizer/entity_normalizer.service.js | 6 ++++++
.../entity_normalizer/entity_normalizer.spec.js | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index ca79df6f..ca2075a4 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -53,6 +53,12 @@ export const parseUser = (data) => {
value: addEmojis(field.value, data.emojis)
}
})
+ output.fields_text = data.fields.map(field => {
+ return {
+ name: field.name.replace(/<[^>]*>/g, ''),
+ value: field.value.replace(/<[^>]*>/g, '')
+ }
+ })
// Utilize avatar_static for gif avatars?
output.profile_image_url = data.avatar
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 cfb380ba..9df84575 100644
--- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -290,6 +290,19 @@ describe('API Entities normalizer', () => {
expect(field).to.have.property('value').that.contains(' {
+ const user = makeMockUserMasto({ emojis: makeMockEmojiMasto(), fields: [{ name: 'user', value: '@user' }] })
+
+ const parsedUser = parseUser(user)
+
+ expect(parsedUser).to.have.property('fields_text').to.be.an('array')
+
+ const field = parsedUser.fields_text[0]
+
+ expect(field).to.have.property('name').that.equal('user')
+ expect(field).to.have.property('value').that.equal('@user')
+ })
+
it('adds hide_follows and hide_followers user settings', () => {
const user = makeMockUserMasto({ pleroma: { hide_followers: true, hide_follows: false, hide_followers_count: false, hide_follows_count: true } })
From 064b59812c715d60526727d42c124375a2bc89d5 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Wed, 19 Feb 2020 21:00:39 +0900
Subject: [PATCH 09/52] Change to use tags removed fields instead of raw fields
---
src/components/user_profile/user_profile.vue | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 5bffba3a..54f2d4b3 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -22,13 +22,13 @@
>
Date: Wed, 25 Mar 2020 20:06:48 +0300
Subject: [PATCH 10/52] after_store: Remove most of StatusNet config usage
Information under `pleromafe` key is equivalent to the one under
`pleroma_fe` key in `/api/pleroma/frontend_configurations`.
All other information had equivalents in `/nodeinfo/2.0.json`, except
`textlimit` and `vapidPublicKey`.
---
src/boot/after_store.js | 51 ++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 18 deletions(-)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index d70e1058..b943ed95 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -13,28 +13,13 @@ const getStatusnetConfig = async ({ store }) => {
const res = await window.fetch('/api/statusnet/config.json')
if (res.ok) {
const data = await res.json()
- const { name, closed: registrationClosed, textlimit, uploadlimit, server, vapidPublicKey, safeDMMentionsEnabled } = data.site
+ const { textlimit, vapidPublicKey } = data.site
- store.dispatch('setInstanceOption', { name: 'name', value: name })
- store.dispatch('setInstanceOption', { name: 'registrationOpen', value: (registrationClosed === '0') })
store.dispatch('setInstanceOption', { name: 'textlimit', value: parseInt(textlimit) })
- store.dispatch('setInstanceOption', { name: 'server', value: server })
- store.dispatch('setInstanceOption', { name: 'safeDM', value: safeDMMentionsEnabled !== '0' })
-
- // TODO: default values for this stuff, added if to not make it break on
- // my dev config out of the box.
- if (uploadlimit) {
- store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadlimit.uploadlimit) })
- store.dispatch('setInstanceOption', { name: 'avatarlimit', value: parseInt(uploadlimit.avatarlimit) })
- store.dispatch('setInstanceOption', { name: 'backgroundlimit', value: parseInt(uploadlimit.backgroundlimit) })
- store.dispatch('setInstanceOption', { name: 'bannerlimit', value: parseInt(uploadlimit.bannerlimit) })
- }
if (vapidPublicKey) {
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })
}
-
- return data.site.pleromafe
} else {
throw (res)
}
@@ -44,6 +29,21 @@ const getStatusnetConfig = async ({ store }) => {
}
}
+const getBackendProvidedConfig = async ({ store }) => {
+ try {
+ const res = await window.fetch('/api/pleroma/frontend_configurations')
+ if (res.ok) {
+ const data = await res.json()
+ return data.pleroma_fe
+ } else {
+ throw (res)
+ }
+ } catch (error) {
+ console.error('Could not load backend-provided frontend config, potentially fatal')
+ console.error(error)
+ }
+}
+
const getStaticConfig = async () => {
try {
const res = await window.fetch('/static/config.json')
@@ -200,13 +200,22 @@ const getNodeInfo = async ({ store }) => {
const data = await res.json()
const metadata = data.metadata
const features = metadata.features
+ store.dispatch('setInstanceOption', { name: 'name', value: metadata.nodeName })
+ store.dispatch('setInstanceOption', { name: 'registrationOpen', value: data.openRegistrations })
store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
+ store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
store.dispatch('setInstanceOption', { name: 'chatAvailable', value: features.includes('chat') })
store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
+ const uploadLimits = metadata.uploadLimits
+ store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
+ store.dispatch('setInstanceOption', { name: 'avatarlimit', value: parseInt(uploadLimits.avatar) })
+ store.dispatch('setInstanceOption', { name: 'backgroundlimit', value: parseInt(uploadLimits.background) })
+ store.dispatch('setInstanceOption', { name: 'bannerlimit', value: parseInt(uploadLimits.banner) })
+
store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: metadata.restrictedNicknames })
store.dispatch('setInstanceOption', { name: 'postFormats', value: metadata.postFormats })
@@ -254,7 +263,7 @@ const getNodeInfo = async ({ store }) => {
const setConfig = async ({ store }) => {
// apiConfig, staticConfig
- const configInfos = await Promise.all([getStatusnetConfig({ store }), getStaticConfig()])
+ const configInfos = await Promise.all([getBackendProvidedConfig({ store }), getStaticConfig()])
const apiConfig = configInfos[0]
const staticConfig = configInfos[1]
@@ -277,6 +286,11 @@ const checkOAuthToken = async ({ store }) => {
const afterStoreSetup = async ({ store, i18n }) => {
const width = windowWidth()
store.dispatch('setMobileLayout', width <= 800)
+
+ const overrides = window.___pleromafe_dev_overrides || {}
+ const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin
+ store.dispatch('setInstanceOption', { name: 'server', value: server })
+
await setConfig({ store })
const { customTheme, customThemeSource } = store.state.config
@@ -301,7 +315,8 @@ const afterStoreSetup = async ({ store, i18n }) => {
getTOS({ store }),
getInstancePanel({ store }),
getStickers({ store }),
- getNodeInfo({ store })
+ getNodeInfo({ store }),
+ getStatusnetConfig({ store })
])
const router = new VueRouter({
From 54fdc220017122c8e30e0fb16f0dd2534fc60947 Mon Sep 17 00:00:00 2001
From: kPherox
Date: Wed, 10 Jun 2020 03:24:55 +0900
Subject: [PATCH 11/52] Add profile fields form
---
src/boot/after_store.js | 2 +
.../settings_modal/tabs/profile_tab.js | 21 +++++++++
.../settings_modal/tabs/profile_tab.scss | 17 +++++++
.../settings_modal/tabs/profile_tab.vue | 46 +++++++++++++++++++
4 files changed, 86 insertions(+)
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 0db03547..87c92a8a 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -207,6 +207,8 @@ const getNodeInfo = async ({ store }) => {
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
+ store.dispatch('setInstanceOption', { name: 'fieldsLimits', value: metadata.fieldsLimits })
+
store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: metadata.restrictedNicknames })
store.dispatch('setInstanceOption', { name: 'postFormats', value: metadata.postFormats })
diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js
index 8658b097..896ff508 100644
--- a/src/components/settings_modal/tabs/profile_tab.js
+++ b/src/components/settings_modal/tabs/profile_tab.js
@@ -1,4 +1,5 @@
import unescape from 'lodash/unescape'
+import merge from 'lodash/merge'
import ImageCropper from 'src/components/image_cropper/image_cropper.vue'
import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
import fileSizeFormatService from 'src/components/../services/file_size_format/file_size_format.js'
@@ -16,6 +17,7 @@ const ProfileTab = {
newLocked: this.$store.state.users.currentUser.locked,
newNoRichText: this.$store.state.users.currentUser.no_rich_text,
newDefaultScope: this.$store.state.users.currentUser.default_scope,
+ newFields: this.$store.state.users.currentUser.fields.map(field => ({ name: field.name, value: field.value })),
hideFollows: this.$store.state.users.currentUser.hide_follows,
hideFollowers: this.$store.state.users.currentUser.hide_followers,
hideFollowsCount: this.$store.state.users.currentUser.hide_follows_count,
@@ -62,6 +64,12 @@ const ProfileTab = {
...this.$store.state.instance.emoji,
...this.$store.state.instance.customEmoji
] })
+ },
+ fieldsLimits () {
+ return this.$store.state.instance.fieldsLimits
+ },
+ maxFields () {
+ return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
}
},
methods: {
@@ -74,6 +82,7 @@ const ProfileTab = {
// Backend notation.
/* eslint-disable camelcase */
display_name: this.newName,
+ fields_attributes: this.newFields.filter(el => el != null),
default_scope: this.newDefaultScope,
no_rich_text: this.newNoRichText,
hide_follows: this.hideFollows,
@@ -85,6 +94,8 @@ const ProfileTab = {
show_role: this.showRole
/* eslint-enable camelcase */
} }).then((user) => {
+ this.newFields.splice(user.fields.length)
+ merge(this.newFields, user.fields)
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
})
@@ -92,6 +103,16 @@ const ProfileTab = {
changeVis (visibility) {
this.newDefaultScope = visibility
},
+ addField () {
+ if (this.newFields.length < this.maxFields) {
+ this.newFields.push({ name: '', value: '' })
+ return true
+ }
+ return false
+ },
+ deleteField (index, event) {
+ this.$delete(this.newFields, index)
+ },
uploadFile (slot, e) {
const file = e.target.files[0]
if (!file) { return }
diff --git a/src/components/settings_modal/tabs/profile_tab.scss b/src/components/settings_modal/tabs/profile_tab.scss
index 4aab81eb..b3dcf42c 100644
--- a/src/components/settings_modal/tabs/profile_tab.scss
+++ b/src/components/settings_modal/tabs/profile_tab.scss
@@ -79,4 +79,21 @@
.setting-subitem {
margin-left: 1.75em;
}
+
+ .profile-fields {
+ display: flex;
+
+ &>.emoji-input {
+ flex: 1 1 auto;
+ margin: 0 .2em .5em;
+ }
+
+ &>.icon-container {
+ width: 20px;
+
+ &>.icon-cancel {
+ vertical-align: sub;
+ }
+ }
+ }
}
diff --git a/src/components/settings_modal/tabs/profile_tab.vue b/src/components/settings_modal/tabs/profile_tab.vue
index fff4f970..2fa3021e 100644
--- a/src/components/settings_modal/tabs/profile_tab.vue
+++ b/src/components/settings_modal/tabs/profile_tab.vue
@@ -95,6 +95,52 @@
{{ $t('settings.discoverable') }}
+