Multiple fixes for CSS, added proper auth checking

This commit is contained in:
Henry Jameson 2020-05-24 02:06:55 +03:00
parent bcebec478e
commit ab74cd4972
8 changed files with 263 additions and 193 deletions

View file

@ -7,10 +7,8 @@ import Interactions from 'components/interactions/interactions.vue'
import DMs from 'components/dm_timeline/dm_timeline.vue' import DMs from 'components/dm_timeline/dm_timeline.vue'
import UserProfile from 'components/user_profile/user_profile.vue' import UserProfile from 'components/user_profile/user_profile.vue'
import Search from 'components/search/search.vue' import Search from 'components/search/search.vue'
import Settings from 'components/settings/settings.vue'
import Registration from 'components/registration/registration.vue' import Registration from 'components/registration/registration.vue'
import PasswordReset from 'components/password_reset/password_reset.vue' import PasswordReset from 'components/password_reset/password_reset.vue'
import UserSettings from 'components/user_settings/user_settings.vue'
import FollowRequests from 'components/follow_requests/follow_requests.vue' import FollowRequests from 'components/follow_requests/follow_requests.vue'
import OAuthCallback from 'components/oauth_callback/oauth_callback.vue' import OAuthCallback from 'components/oauth_callback/oauth_callback.vue'
import Notifications from 'components/notifications/notifications.vue' import Notifications from 'components/notifications/notifications.vue'
@ -56,12 +54,10 @@ export default (store) => {
{ name: 'external-user-profile', path: '/users/:id', component: UserProfile }, { name: 'external-user-profile', path: '/users/:id', component: UserProfile },
{ name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute }, { name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute },
{ name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute }, { name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute },
{ name: 'settings', path: '/settings', component: Settings },
{ name: 'registration', path: '/registration', component: Registration }, { name: 'registration', path: '/registration', component: Registration },
{ name: 'password-reset', path: '/password-reset', component: PasswordReset, props: true }, { name: 'password-reset', path: '/password-reset', component: PasswordReset, props: true },
{ name: 'registration-token', path: '/registration/:token', component: Registration }, { name: 'registration-token', path: '/registration/:token', component: Registration },
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests, beforeEnter: validateAuthenticatedRoute }, { name: 'friend-requests', path: '/friend-requests', component: FollowRequests, beforeEnter: validateAuthenticatedRoute },
{ name: 'user-settings', path: '/user-settings', component: UserSettings, beforeEnter: validateAuthenticatedRoute },
{ name: 'notifications', path: '/:username/notifications', component: Notifications, beforeEnter: validateAuthenticatedRoute }, { name: 'notifications', path: '/:username/notifications', component: Notifications, beforeEnter: validateAuthenticatedRoute },
{ name: 'login', path: '/login', component: AuthForm }, { name: 'login', path: '/login', component: AuthForm },
{ name: 'chat', path: '/chat', component: ChatPanel, props: () => ({ floating: false }) }, { name: 'chat', path: '/chat', component: ChatPanel, props: () => ({ floating: false }) },

View file

@ -1,9 +1,9 @@
<template> <template>
<div <div
v-show="isOpen" v-show="isOpen"
v-body-scroll-lock="isOpen" v-body-scroll-lock="isOpen && !noBackground"
class="modal-view" class="modal-view"
:class="{ 'modal-background': !noBackground }" :class="classes"
@click.self="$emit('backdropClicked')" @click.self="$emit('backdropClicked')"
> >
<slot /> <slot />
@ -21,6 +21,14 @@ export default {
type: Boolean, type: Boolean,
default: false default: false
} }
},
computed: {
classes () {
return {
'modal-background': !this.noBackground,
'open': this.isOpen
}
}
} }
} }
</script> </script>
@ -40,6 +48,7 @@ export default {
pointer-events: none; pointer-events: none;
animation-duration: 0.2s; animation-duration: 0.2s;
animation-name: modal-background-fadein; animation-name: modal-background-fadein;
opacity: 0;
> * { > * {
pointer-events: initial; pointer-events: initial;
@ -50,8 +59,8 @@ export default {
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.5);
} }
body:not(.scroll-locked) & { &.open {
opacity: 0; opacity: 1;
} }
} }

View file

@ -1,12 +1,21 @@
@import 'src/_variables.scss'; @import 'src/_variables.scss';
.settings-modal { .settings-modal {
overflow: hidden;
.settings_tab-switcher { .settings_tab-switcher {
height: 100%; height: 100%;
} }
&.peek { &.peek {
.settings-modal-panel { .settings-modal-panel {
transform: translateY(calc(100% - 50px)); /* Explanation:
* Modal is positioned vertically centered.
* 100vh - 100% = Distance between modal's top+bottom boundaries and screen
* (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen
* + 100% - we move modal completely off-screen, it's top boundary touches
* bottom of the screen
* - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible
*/
transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));
} }
} }
@ -25,17 +34,22 @@
.panel-body { .panel-body {
height: 100%; height: 100%;
overflow-y: hidden; overflow-y: hidden;
}
.setting-item {
border-bottom: 2px solid var(--fg, $fallback--fg);
margin: 1em 1em 1.4em;
padding-bottom: 1.4em;
.btn { .btn {
min-height: 28px; min-height: 28px;
min-width: 10em; min-width: 10em;
padding: 0 2em; padding: 0 2em;
} }
}
.full-height {
height: 100%;
}
.setting-item {
border-bottom: 2px solid var(--fg, $fallback--fg);
margin: 1em 1em 1.4em;
padding-bottom: 1.4em;
> div { > div {
margin-bottom: .5em; margin-bottom: .5em;

View file

@ -1,6 +1,5 @@
<template> <template>
<Modal <Modal
v-if="isLoggedIn && !resettingForm"
:is-open="modalActivated" :is-open="modalActivated"
class="settings-modal" class="settings-modal"
:class="{ peek: modalPeeked }" :class="{ peek: modalPeeked }"
@ -25,15 +24,57 @@
:scrollableTabs="true" :scrollableTabs="true"
ref="tabSwitcher" ref="tabSwitcher"
> >
<div :label="$t('settings.general')"><GeneralTab /></div> <div
<div :label="$t('settings.profile_tab')"><ProfileTab /></div> :label="$t('settings.general')"
<div :label="$t('settings.security_tab')"><SecurityTab /></div> >
<div :label="$t('settings.filtering')"><FilteringTab /></div> <GeneralTab />
<div :label="$t('settings.theme')"><ThemeTab /></div> </div>
<div :label="$t('settings.notifications')"><NotificationsTab /></div> <div v-if="isLoggedIn"
<div :label="$t('settings.data_import_export_tab')"><DataImportExportTab /></div> :label="$t('settings.profile_tab')"
<div :label="$t('settings.mutes_and_blocks')"><MutesAndBlocksTab /></div> >
<div :label="$t('settings.version.title')"><VersionTab /></div> <ProfileTab />
</div>
<div
v-if="isLoggedIn"
:label="$t('settings.security_tab')"
>
<SecurityTab />
</div>
<div
:label="$t('settings.filtering')"
>
<FilteringTab />
</div>
<div
:label="$t('settings.theme')"
>
<ThemeTab />
</div>
<div
v-if="isLoggedIn"
:label="$t('settings.notifications')"
>
<NotificationsTab />
</div>
<div
v-if="isLoggedIn"
:label="$t('settings.data_import_export_tab')"
>
<DataImportExportTab />
</div>
<div
v-if="isLoggedIn"
:label="$t('settings.mutes_and_blocks')"
:fullHeight="true"
class="full-height"
>
<MutesAndBlocksTab />
</div>
<div
:label="$t('settings.version.title')"
>
<VersionTab />
</div>
</tab-switcher> </tab-switcher>
</div> </div>
</div> </div>

View file

@ -1,173 +1,176 @@
<template> <template>
<tab-switcher> <tab-switcher
<div :label="$t('settings.blocks_tab')"> :scrollableTabs="true"
<div class="profile-edit-usersearch-wrapper"> class="mutes-and-blocks-tab"
<Autosuggest >
:filter="filterUnblockedUsers" <div :label="$t('settings.blocks_tab')">
:query="queryUserIds" <div class="usersearch-wrapper">
:placeholder="$t('settings.search_user_to_block')" <Autosuggest
> :filter="filterUnblockedUsers"
<BlockCard :query="queryUserIds"
slot-scope="row" :placeholder="$t('settings.search_user_to_block')"
:user-id="row.item"
/>
</Autosuggest>
</div>
<BlockList
:refresh="true"
:get-key="i => i"
> >
<template <BlockCard
slot="header" slot-scope="row"
slot-scope="{selected}" :user-id="row.item"
> />
<div class="profile-edit-bulk-actions"> </Autosuggest>
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => blockUsers(selected)"
>
{{ $t('user_card.block') }}
<template slot="progress">
{{ $t('user_card.block_progress') }}
</template>
</ProgressButton>
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => unblockUsers(selected)"
>
{{ $t('user_card.unblock') }}
<template slot="progress">
{{ $t('user_card.unblock_progress') }}
</template>
</ProgressButton>
</div>
</template>
<template
slot="item"
slot-scope="{item}"
>
<BlockCard :user-id="item" />
</template>
<template slot="empty">
{{ $t('settings.no_blocks') }}
</template>
</BlockList>
</div> </div>
<BlockList
<div :label="$t('settings.mutes_tab')"> :refresh="true"
<tab-switcher> :get-key="i => i"
<div label="Users"> >
<div class="profile-edit-usersearch-wrapper"> <template
<Autosuggest slot="header"
:filter="filterUnMutedUsers" slot-scope="{selected}"
:query="queryUserIds" >
:placeholder="$t('settings.search_user_to_mute')" <div class="bulk-actions">
> <ProgressButton
<MuteCard v-if="selected.length > 0"
slot-scope="row" class="btn btn-default bulk-action-button"
:user-id="row.item" :click="() => blockUsers(selected)"
/>
</Autosuggest>
</div>
<MuteList
:refresh="true"
:get-key="i => i"
> >
<template {{ $t('user_card.block') }}
slot="header" <template slot="progress">
slot-scope="{selected}" {{ $t('user_card.block_progress') }}
>
<div class="profile-edit-bulk-actions">
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => muteUsers(selected)"
>
{{ $t('user_card.mute') }}
<template slot="progress">
{{ $t('user_card.mute_progress') }}
</template>
</ProgressButton>
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => unmuteUsers(selected)"
>
{{ $t('user_card.unmute') }}
<template slot="progress">
{{ $t('user_card.unmute_progress') }}
</template>
</ProgressButton>
</div>
</template> </template>
<template </ProgressButton>
slot="item" <ProgressButton
slot-scope="{item}" v-if="selected.length > 0"
> class="btn btn-default"
<MuteCard :user-id="item" /> :click="() => unblockUsers(selected)"
</template>
<template slot="empty">
{{ $t('settings.no_mutes') }}
</template>
</MuteList>
</div>
<div :label="$t('settings.domain_mutes')">
<div class="profile-edit-domain-mute-form">
<input
v-model="newDomainToMute"
:placeholder="$t('settings.type_domains_to_mute')"
type="text"
@keyup.enter="muteDomain"
>
<ProgressButton
class="btn btn-default"
:click="muteDomain"
>
{{ $t('domain_mute_card.mute') }}
<template slot="progress">
{{ $t('domain_mute_card.mute_progress') }}
</template>
</ProgressButton>
</div>
<DomainMuteList
:refresh="true"
:get-key="i => i"
> >
<template {{ $t('user_card.unblock') }}
slot="header" <template slot="progress">
slot-scope="{selected}" {{ $t('user_card.unblock_progress') }}
>
<div class="profile-edit-bulk-actions">
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => unmuteDomains(selected)"
>
{{ $t('domain_mute_card.unmute') }}
<template slot="progress">
{{ $t('domain_mute_card.unmute_progress') }}
</template>
</ProgressButton>
</div>
</template> </template>
<template </ProgressButton>
slot="item"
slot-scope="{item}"
>
<DomainMuteCard :domain="item" />
</template>
<template slot="empty">
{{ $t('settings.no_mutes') }}
</template>
</DomainMuteList>
</div> </div>
</tab-switcher> </template>
</div> <template
</tab-switcher> slot="item"
slot-scope="{item}"
>
<BlockCard :user-id="item" />
</template>
<template slot="empty">
{{ $t('settings.no_blocks') }}
</template>
</BlockList>
</div>
<div :label="$t('settings.mutes_tab')">
<tab-switcher>
<div label="Users">
<div class="usersearch-wrapper">
<Autosuggest
:filter="filterUnMutedUsers"
:query="queryUserIds"
:placeholder="$t('settings.search_user_to_mute')"
>
<MuteCard
slot-scope="row"
:user-id="row.item"
/>
</Autosuggest>
</div>
<MuteList
:refresh="true"
:get-key="i => i"
>
<template
slot="header"
slot-scope="{selected}"
>
<div class="bulk-actions">
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => muteUsers(selected)"
>
{{ $t('user_card.mute') }}
<template slot="progress">
{{ $t('user_card.mute_progress') }}
</template>
</ProgressButton>
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => unmuteUsers(selected)"
>
{{ $t('user_card.unmute') }}
<template slot="progress">
{{ $t('user_card.unmute_progress') }}
</template>
</ProgressButton>
</div>
</template>
<template
slot="item"
slot-scope="{item}"
>
<MuteCard :user-id="item" />
</template>
<template slot="empty">
{{ $t('settings.no_mutes') }}
</template>
</MuteList>
</div>
<div :label="$t('settings.domain_mutes')">
<div class="domain-mute-form">
<input
v-model="newDomainToMute"
:placeholder="$t('settings.type_domains_to_mute')"
type="text"
@keyup.enter="muteDomain"
>
<ProgressButton
class="btn btn-default domain-mute-button"
:click="muteDomain"
>
{{ $t('domain_mute_card.mute') }}
<template slot="progress">
{{ $t('domain_mute_card.mute_progress') }}
</template>
</ProgressButton>
</div>
<DomainMuteList
:refresh="true"
:get-key="i => i"
>
<template
slot="header"
slot-scope="{selected}"
>
<div class="bulk-actions">
<ProgressButton
v-if="selected.length > 0"
class="btn btn-default"
:click="() => unmuteDomains(selected)"
>
{{ $t('domain_mute_card.unmute') }}
<template slot="progress">
{{ $t('domain_mute_card.unmute_progress') }}
</template>
</ProgressButton>
</div>
</template>
<template
slot="item"
slot-scope="{item}"
>
<DomainMuteCard :domain="item" />
</template>
<template slot="empty">
{{ $t('settings.no_mutes') }}
</template>
</DomainMuteList>
</div>
</tab-switcher>
</div>
</tab-switcher>
</template> </template>
<script src="./mutes_and_blocks_tab.js"></script> <script src="./mutes_and_blocks_tab.js"></script>
<!-- <style lang="scss" src="./profile.scss"></style> --> <style lang="scss" src="./mutes_and_blocks_tab.scss"></style>

View file

@ -1,5 +1,6 @@
@import 'src/_variables.scss'; @import 'src/_variables.scss';
.theme-tab { .theme-tab {
padding-bottom: 2em;
.theme-warning { .theme-warning {
display: flex; display: flex;
align-items: baseline; align-items: baseline;

View file

@ -69,7 +69,6 @@ export default Vue.component('tab-switcher', {
if (!slot.tag) return if (!slot.tag) return
const classesTab = ['tab'] const classesTab = ['tab']
const classesWrapper = ['tab-wrapper'] const classesWrapper = ['tab-wrapper']
if (this.activeIndex === index) { if (this.activeIndex === index) {
classesTab.push('active') classesTab.push('active')
classesWrapper.push('active') classesWrapper.push('active')
@ -101,12 +100,17 @@ export default Vue.component('tab-switcher', {
const contents = this.$slots.default.map((slot, index) => { const contents = this.$slots.default.map((slot, index) => {
if (!slot.tag) return if (!slot.tag) return
const active = this.activeIndex === index const active = this.activeIndex === index
const classes = [ active ? 'active' : 'hidden' ]
if (slot.data.attrs.fullHeight) {
classes.push('full-height')
}
if (this.renderOnlyFocused) { if (this.renderOnlyFocused) {
return active return active
? <div class="active">{slot}</div> ? <div class={classes.join(' ')}>{slot}</div>
: <div class="hidden"></div> : <div class={classes.join(' ')}></div>
} }
return <div class={active ? 'active' : 'hidden' }>{slot}</div> return <div class={classes.join(' ')}>{slot}</div>
}) })
return ( return (

View file

@ -59,7 +59,6 @@
flex: 1 0 auto; flex: 1 0 auto;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
padding-top: 5px;
flex-direction: column; flex-direction: column;
&::after { &::after {
content: ''; content: '';
@ -78,6 +77,9 @@
border-right-color: $fallback--border; border-right-color: $fallback--border;
border-right-color: var(--border, $fallback--border); border-right-color: var(--border, $fallback--border);
} }
&:last-child .tab {
margin-bottom: 0;
}
} }
.tab { .tab {
box-sizing: content-box; box-sizing: content-box;
@ -87,8 +89,8 @@
min-width: 1px; min-width: 1px;
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
// padding-right: 200px; padding-right: calc(1em + 200px);
// margin-right: 6px - 200px; margin-right: 6px - 200px;
margin-left: 6px; margin-left: 6px;
} }