From 9336140486f50159b935001b7ebadf3d9bda89ec Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Jan 2020 00:37:19 +0200 Subject: massively improved initial theme loading code, added checks and warnings when loading theme files (import/localStorage/defaults) --- src/boot/after_store.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src/boot') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 228a0497..6c4f0e1b 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -5,6 +5,8 @@ import App from '../App.vue' import { windowWidth } from '../services/window_utils/window_utils' import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js' import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' +import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' +import { applyTheme } from '../services/style_setter/style_setter.js' const getStatusnetConfig = async ({ store }) => { try { @@ -261,7 +263,7 @@ const checkOAuthToken = async ({ store }) => { try { await store.dispatch('loginUser', store.getters.getUserToken()) } catch (e) { - console.log(e) + console.error(e) } } resolve() @@ -269,23 +271,29 @@ const checkOAuthToken = async ({ store }) => { } const afterStoreSetup = async ({ store, i18n }) => { - if (store.state.config.customTheme) { - // This is a hack to deal with async loading of config.json and themes - // See: style_setter.js, setPreset() - window.themeLoaded = true - store.dispatch('setOption', { - name: 'customTheme', - value: store.state.config.customTheme - }) - } - const width = windowWidth() store.dispatch('setMobileLayout', width <= 800) + await setConfig({ store }) + + const { customTheme, customThemeSource } = store.state.config + const { theme } = store.state.instance + const customThemePresent = customThemeSource || customTheme + + if (customThemePresent) { + if (customThemeSource && customThemeSource.version === CURRENT_VERSION) { + applyTheme(customThemeSource) + } else { + applyTheme(customTheme) + } + } else if (theme) { + // do nothing, it will load asynchronously + } else { + console.error('Failed to load any theme!') + } // Now we can try getting the server settings and logging in await Promise.all([ checkOAuthToken({ store }), - setConfig({ store }), getTOS({ store }), getInstancePanel({ store }), getStickers({ store }), -- cgit v1.2.3-70-g09d2 From 8de7eabd8fdfc9f97fb262552f0cca9fd6da95eb Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 22 Jan 2020 23:26:24 +0200 Subject: v2 compatibility fixes --- src/boot/after_store.js | 2 +- src/components/style_switcher/style_switcher.js | 7 +++- src/services/color_convert/color_convert.js | 5 +-- src/services/style_setter/style_setter.js | 49 ++++++++++++++++++++++++- src/services/theme_data/theme_data.service.js | 12 +++--- 5 files changed, 62 insertions(+), 13 deletions(-) (limited to 'src/boot') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 6c4f0e1b..f61e9252 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -280,7 +280,7 @@ const afterStoreSetup = async ({ store, i18n }) => { const customThemePresent = customThemeSource || customTheme if (customThemePresent) { - if (customThemeSource && customThemeSource.version === CURRENT_VERSION) { + if (customThemeSource && customThemeSource.themeEngineVersion === CURRENT_VERSION) { applyTheme(customThemeSource) } else { applyTheme(customTheme) diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index 27df0d10..76e6cdb7 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -12,7 +12,8 @@ import { generateFonts, composePreset, getThemes, - shadows2to3 + shadows2to3, + colors2to3 } from '../../services/style_setter/style_setter.js' import { CURRENT_VERSION, @@ -588,7 +589,9 @@ export default { const opacity = input.opacity const shadows = input.shadows || {} const fonts = input.fonts || {} - const colors = input.colors || input + const colors = !input.themeEngineVersion + ? colors2to3(input.colors) + : input.colors || input if (version === 0) { if (input.version) version = input.version diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js index 6b228a58..93cb1ba6 100644 --- a/src/services/color_convert/color_convert.js +++ b/src/services/color_convert/color_convert.js @@ -185,10 +185,9 @@ export const rgba2css = function (rgba) { * @param {Boolean} preserve - try to preserve intended text color's hue/saturation (i.e. no BW) */ export const getTextColor = function (bg, text, preserve) { - const bgIsLight = relativeLuminance(bg) > 0.5 - const textIsLight = relativeLuminance(text) > 0.5 + const contrast = getContrastRatio(bg, text) - if ((bgIsLight && textIsLight) || (!bgIsLight && !textIsLight)) { + if (contrast < 4.5) { const base = typeof text.a !== 'undefined' ? { a: text.a } : {} const result = Object.assign(base, invertLightness(text).rgb) if (!preserve && getContrastRatio(bg, result) < 4.5) { diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 9610d799..b43eb0dd 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -110,7 +110,9 @@ const getCssShadowFilter = (input) => { } export const generateColors = (themeData) => { - const sourceColors = themeData.colors || themeData + const sourceColors = !themeData.themeEngineVersion + ? colors2to3(themeData.colors) + : themeData.colors || themeData const isLightOnDark = convert(sourceColors.bg).hsl.l < convert(sourceColors.text).hsl.l const mod = isLightOnDark ? 1 : -1 @@ -283,9 +285,12 @@ export const DEFAULT_SHADOWS = { }] } export const generateShadows = (input, colors, mod) => { + const inputShadows = !input.themeEngineVersion + ? shadows2to3(input.shadows) + : input.shadows || {} const shadows = Object.entries({ ...DEFAULT_SHADOWS, - ...(input.shadows || {}) + ...inputShadows }).reduce((shadowsAcc, [slotName, shadowDefs]) => { const newShadow = shadowDefs.reduce((shadowAcc, def) => [ ...shadowAcc, @@ -374,6 +379,46 @@ export const getThemes = () => { }, {}) }) } +export const colors2to3 = (colors) => { + return Object.entries(colors).reduce((acc, [slotName, color]) => { + const btnStates = ['', 'Pressed', 'Disabled', 'Toggled'] + const btnPositions = ['', 'Panel', 'TopBar'] + switch (slotName) { + case 'lightBg': + return { ...acc, highlight: color } + case 'btn': + return { + ...acc, + ...btnStates.reduce((stateAcc, state) => ({ ...stateAcc, ['btn' + state]: color }), {}) + } + case 'btnText': + console.log( + btnPositions + .map(position => btnStates.map(state => state + position)) + .flat() + .reduce( + (statePositionAcc, statePosition) => + ({ ...statePositionAcc, ['btn' + statePosition + 'Text']: color }) + , {} + ) + ) + return { + ...acc, + ...btnPositions + .map(position => btnStates.map(state => state + position)) + .flat() + .reduce( + (statePositionAcc, statePosition) => + ({ ...statePositionAcc, ['btn' + statePosition + 'Text']: color }) + , {} + ) + } + default: + console.log('aaa', slotName, color, acc) + return { ...acc, [slotName]: color } + } + }, {}) +} /** * This handles compatibility issues when importing v2 theme's shadows to current format diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js index 8c114004..2cae85de 100644 --- a/src/services/theme_data/theme_data.service.js +++ b/src/services/theme_data/theme_data.service.js @@ -283,12 +283,12 @@ export const SLOT_INHERITANCE = { opacity: 'panel' }, panelText: { - depends: ['fgText'], + depends: ['text'], layer: 'panel', textColor: true }, panelFaint: { - depends: ['fgText'], + depends: ['text'], layer: 'panel', opacity: 'faint', textColor: true @@ -302,7 +302,7 @@ export const SLOT_INHERITANCE = { // Top bar topBar: '--fg', topBarText: { - depends: ['fgText'], + depends: ['text'], layer: 'topBar', textColor: true }, @@ -313,7 +313,9 @@ export const SLOT_INHERITANCE = { }, // Tabs - tab: '--btn', + tab: { + depends: ['btn'] + }, tabText: { depends: ['btnText'], layer: 'btn', @@ -331,7 +333,7 @@ export const SLOT_INHERITANCE = { opacity: 'btn' }, btnText: { - depends: ['fgText'], + depends: ['text'], layer: 'btn', textColor: true }, -- cgit v1.2.3-70-g09d2 From 0dcc3bf2fe78ec715a0d492281045426ab194457 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Thu, 13 Feb 2020 22:35:46 +0300 Subject: after_store: Fix failing to parse nodeinfo when mrf transparency is disabled Closes #772 --- src/boot/after_store.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/boot') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 0bb1b2b4..4e043b35 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -221,9 +221,16 @@ const getNodeInfo = async ({ store }) => { const frontendVersion = window.___pleromafe_commit_hash store.dispatch('setInstanceOption', { name: 'frontendVersion', value: frontendVersion }) - store.dispatch('setInstanceOption', { name: 'tagPolicyAvailable', value: metadata.federation.mrf_policies.includes('TagPolicy') }) const federation = metadata.federation + + store.dispatch('setInstanceOption', { + name: 'tagPolicyAvailable', + value: typeof federation.mrf_policies === 'undefined' + ? false + : metadata.federation.mrf_policies.includes('TagPolicy') + }) + store.dispatch('setInstanceOption', { name: 'federationPolicy', value: federation }) store.dispatch('setInstanceOption', { name: 'federating', -- cgit v1.2.3-70-g09d2 From 86561592d002b08d6b2cd9549e8057a4ffd091cb Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 24 Feb 2020 11:19:00 -0600 Subject: First attempt at not requiring email address for registration --- src/boot/after_store.js | 3 +++ src/components/registration/registration.js | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/boot') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index d70e1058..9fb9a853 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -241,6 +241,9 @@ const getNodeInfo = async ({ store }) => { : federation.enabled }) + const accountActivationRequired = metadata.accountActivationRequired + store.dispatch('setInstanceOption', { name: 'accountActivationRequired', value: accountActivationRequired }) + const accounts = metadata.staffAccounts resolveStaffAccounts({ store, accounts }) } else { diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js index ace8cc7c..fd2942a5 100644 --- a/src/components/registration/registration.js +++ b/src/components/registration/registration.js @@ -1,5 +1,5 @@ import { validationMixin } from 'vuelidate' -import { required, sameAs } from 'vuelidate/lib/validators' +import { required, requiredIf, sameAs } from 'vuelidate/lib/validators' import { mapActions, mapState } from 'vuex' const registration = { @@ -16,7 +16,7 @@ const registration = { }), validations: { user: { - email: { required }, + email: requiredIf('accountActivationRequired'), username: { required }, fullname: { required }, password: { required }, @@ -24,6 +24,11 @@ const registration = { required, sameAsPassword: sameAs('password') } + }, + nested: { + required: requiredIf(function (nestedModel) { + return this.accountActivationRequired + }) } }, created () { -- cgit v1.2.3-70-g09d2 From 6bb75a3a6d8452a3e1b88085fe87cf27386f222c Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 21 Apr 2020 23:27:51 +0300 Subject: make relationships separate from users --- src/boot/after_store.js | 3 ++ src/components/account_actions/account_actions.js | 2 +- src/components/account_actions/account_actions.vue | 8 ++--- src/components/basic_user_card/basic_user_card.vue | 2 +- src/components/block_card/block_card.js | 5 ++- src/components/follow_button/follow_button.js | 14 ++++---- src/components/follow_card/follow_card.js | 3 ++ src/components/follow_card/follow_card.vue | 5 +-- src/components/mute_card/mute_card.js | 9 ++++-- src/components/notification/notification.js | 2 +- src/components/notification/notification.vue | 2 +- src/components/side_drawer/side_drawer.vue | 2 +- src/components/status/status.js | 15 +++++++-- src/components/status/status.vue | 2 +- src/components/user_card/user_card.js | 8 ++++- src/components/user_card/user_card.vue | 15 +++++---- src/components/user_panel/user_panel.vue | 2 +- src/components/user_profile/user_profile.vue | 2 +- src/components/user_settings/user_settings.js | 8 ++--- src/modules/users.js | 37 ++++++++-------------- src/services/api/api.service.js | 4 ++- .../entity_normalizer/entity_normalizer.service.js | 25 +++++++++------ .../follow_manipulate/follow_manipulate.js | 15 +++++---- .../notifications_fetcher.service.js | 1 - .../timeline_fetcher/timeline_fetcher.service.js | 2 ++ 25 files changed, 112 insertions(+), 81 deletions(-) (limited to 'src/boot') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index d70e1058..1522d4f0 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -304,6 +304,9 @@ const afterStoreSetup = async ({ store, i18n }) => { getNodeInfo({ store }) ]) + // Start fetching things that don't need to block the UI + store.dispatch('fetchMutes') + const router = new VueRouter({ mode: 'history', routes: routes(store), diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js index 5d7ecf7e..0826c275 100644 --- a/src/components/account_actions/account_actions.js +++ b/src/components/account_actions/account_actions.js @@ -3,7 +3,7 @@ import Popover from '../popover/popover.vue' const AccountActions = { props: [ - 'user' + 'user', 'relationship' ], data () { return { } diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue index 483783cf..744b77d5 100644 --- a/src/components/account_actions/account_actions.vue +++ b/src/components/account_actions/account_actions.vue @@ -9,16 +9,16 @@ class="account-tools-popover" >