diff --git a/changelog.d/migrate-auth-flow-pinia.skip b/changelog.d/migrate-auth-flow-pinia.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/small-fixes.skip b/changelog.d/small-fixes.skip new file mode 100644 index 000000000..e69de29bb diff --git a/changelog.d/unify-show-hide-buttons.add b/changelog.d/unify-show-hide-buttons.add new file mode 100644 index 000000000..663bc38a5 --- /dev/null +++ b/changelog.d/unify-show-hide-buttons.add @@ -0,0 +1 @@ +Unify show/hide content buttons diff --git a/index.html b/index.html index f279ed01a..86d15971b 100644 --- a/index.html +++ b/index.html @@ -135,6 +135,7 @@ +
diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 39fc6f6f0..05ddda982 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -21,6 +21,7 @@ import { useOAuthStore } from 'src/stores/oauth' import { useI18nStore } from 'src/stores/i18n' import { useInterfaceStore } from 'src/stores/interface' import { useAnnouncementsStore } from 'src/stores/announcements' +import { useAuthFlowStore } from 'src/stores/auth_flow' let staticInitialResults = null @@ -156,7 +157,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => { : config.logoMargin }) copyInstanceOption('logoLeft') - store.commit('authFlow/setInitialStrategy', config.loginMethod) + useAuthFlowStore().setInitialStrategy(config.loginMethod) copyInstanceOption('redirectRootNoLogin') copyInstanceOption('redirectRootLogin') diff --git a/src/components/auth_form/auth_form.js b/src/components/auth_form/auth_form.js index a86a3dca2..243cbf574 100644 --- a/src/components/auth_form/auth_form.js +++ b/src/components/auth_form/auth_form.js @@ -2,7 +2,8 @@ import { h, resolveComponent } from 'vue' import LoginForm from '../login_form/login_form.vue' import MFARecoveryForm from '../mfa_form/recovery_form.vue' import MFATOTPForm from '../mfa_form/totp_form.vue' -import { mapGetters } from 'vuex' +import { mapState } from 'pinia' +import { useAuthFlowStore } from 'src/stores/auth_flow' const AuthForm = { name: 'AuthForm', @@ -15,7 +16,7 @@ const AuthForm = { if (this.requiredRecovery) { return 'MFARecoveryForm' } return 'LoginForm' }, - ...mapGetters('authFlow', ['requiredTOTP', 'requiredRecovery']) + ...mapState(useAuthFlowStore, ['requiredTOTP', 'requiredRecovery']) }, components: { MFARecoveryForm, diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue index 26b67cfe8..bcdf435fc 100644 --- a/src/components/color_input/color_input.vue +++ b/src/components/color_input/color_input.vue @@ -26,7 +26,7 @@ class="textColor unstyled" :class="{ disabled: !present || disabled }" type="text" - :value="modelValue || fallback" + :value="modelValue ?? fallback" :disabled="!present || disabled" @input="updateValue($event.target.value)" > diff --git a/src/components/login_form/login_form.js b/src/components/login_form/login_form.js index ed3f5dfc6..9566aa903 100644 --- a/src/components/login_form/login_form.js +++ b/src/components/login_form/login_form.js @@ -1,7 +1,8 @@ -import { mapState, mapGetters, mapActions, mapMutations } from 'vuex' -import { mapStores } from 'pinia' +import { mapState } from 'vuex' +import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia' import oauthApi from '../../services/new_api/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js' +import { useAuthFlowStore } from 'src/stores/auth_flow.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes @@ -25,13 +26,10 @@ const LoginForm = { instance: state => state.instance, loggingIn: state => state.users.loggingIn, }), - ...mapGetters( - 'authFlow', ['requiredPassword', 'requiredToken', 'requiredMFA'] - ) + ...mapPiniaState(useAuthFlowStore, ['requiredPassword', 'requiredToken', 'requiredMFA']) }, methods: { - ...mapMutations('authFlow', ['requireMFA']), - ...mapActions({ login: 'authFlow/login' }), + ...mapActions(useAuthFlowStore, ['requireMFA', 'login']), submit () { this.isTokenAuth ? this.submitToken() : this.submitPassword() }, diff --git a/src/components/mfa_form/recovery_form.js b/src/components/mfa_form/recovery_form.js index 2d0f4fdff..84479b1ec 100644 --- a/src/components/mfa_form/recovery_form.js +++ b/src/components/mfa_form/recovery_form.js @@ -1,7 +1,8 @@ import mfaApi from '../../services/new_api/mfa.js' -import { mapState, mapGetters, mapActions, mapMutations } from 'vuex' -import { mapStores } from 'pinia' +import { mapState } from 'vuex' +import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia' import { useOAuthStore } from 'src/stores/oauth.js' +import { useAuthFlowStore } from 'src/stores/auth_flow.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes @@ -17,8 +18,8 @@ export default { error: false }), computed: { - ...mapGetters({ - authSettings: 'authFlow/settings' + ...mapPiniaState(useAuthFlowStore, { + authSettings: store => store.settings }), ...mapStores(useOAuthStore), ...mapState({ @@ -26,8 +27,7 @@ export default { }) }, methods: { - ...mapMutations('authFlow', ['requireTOTP', 'abortMFA']), - ...mapActions({ login: 'authFlow/login' }), + ...mapActions(useAuthFlowStore, ['requireTOTP', 'abortMFA', 'login']), clearError () { this.error = false }, focusOnCodeInput () { diff --git a/src/components/mfa_form/totp_form.js b/src/components/mfa_form/totp_form.js index 857d055ff..e369d8a5d 100644 --- a/src/components/mfa_form/totp_form.js +++ b/src/components/mfa_form/totp_form.js @@ -1,7 +1,8 @@ import mfaApi from '../../services/new_api/mfa.js' -import { mapState, mapGetters, mapActions, mapMutations } from 'vuex' -import { mapStores } from 'pinia' +import { mapState } from 'vuex' +import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia' import { useOAuthStore } from 'src/stores/oauth.js' +import { useAuthFlowStore } from 'src/stores/auth_flow.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes @@ -17,8 +18,8 @@ export default { error: false }), computed: { - ...mapGetters({ - authSettings: 'authFlow/settings' + ...mapPiniaState(useAuthFlowStore, { + authSettings: store => store.settings }), ...mapStores(useOAuthStore), ...mapState({ @@ -26,8 +27,7 @@ export default { }) }, methods: { - ...mapMutations('authFlow', ['requireRecovery', 'abortMFA']), - ...mapActions({ login: 'authFlow/login' }), + ...mapActions(useAuthFlowStore, ['requireRecovery', 'abortMFA', 'login']), clearError () { this.error = false }, focusOnCodeInput () { diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index 8324263cd..82c63f503 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -372,6 +372,9 @@ export default { const path = getPath(component, directive) usedRule = get(real, path) // get real + if (usedRule === '') { + return usedRule + } if (!usedRule) { usedRule = get(fallback, path) } @@ -379,7 +382,7 @@ export default { return postProcess(usedRule) }, set (value) { - if (value) { + if (value != null) { set(allEditedRules.value, getPath(component, directive), value) } else { unset(allEditedRules.value, getPath(component, directive)) diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js index b8f6f9a0b..aa334499e 100644 --- a/src/components/status_body/status_body.js +++ b/src/components/status_body/status_body.js @@ -72,6 +72,23 @@ const StatusContent = { hideTallStatus () { return this.mightHideBecauseTall && !this.showingTall }, + shouldShowToggle () { + return this.mightHideBecauseSubject || this.mightHideBecauseTall + }, + toggleButtonClasses () { + return { + 'cw-status-hider': !this.showingMore && this.mightHideBecauseSubject, + 'tall-status-hider': !this.showingMore && this.mightHideBecauseTall, + 'status-unhider': this.showingMore, + } + }, + toggleText () { + if (this.showingMore) { + return this.mightHideBecauseSubject ? this.$t('status.hide_content') : this.$t('general.show_less') + } else { + return this.mightHideBecauseSubject ? this.$t('status.show_content') : this.$t('general.show_more') + } + }, showingMore () { return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject) }, diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss index 07fc8ef45..f89ea8d89 100644 --- a/src/components/status_body/status_body.scss +++ b/src/components/status_body/status_body.scss @@ -62,7 +62,6 @@ &.-tall-status { position: relative; height: 16em; - overflow: hidden; z-index: 1; .media-body { @@ -82,6 +81,10 @@ mask-composite: exclude; } } + + &.-expanded { + overflow: visible; + } } & .tall-status-hider, @@ -95,6 +98,13 @@ text-align: center; } + .status-unhider { + margin-top: auto; + position: sticky; + bottom: 0; + padding-bottom: 1em; + } + .tall-status-hider { position: absolute; height: 5em; @@ -118,6 +128,10 @@ } } + .toggle-button { + padding: 0.5em; + } + &.-compact { align-items: start; flex-direction: row; @@ -166,11 +180,11 @@ line-height: inherit; margin: 0; border: none; - display: inline-block; } .text-wrapper { display: inline-block; + width: 100%; } } } diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue index 16894021b..0fc024b04 100644 --- a/src/components/status_body/status_body.vue +++ b/src/components/status_body/status_body.vue @@ -31,17 +31,9 @@