Merge branch 'appearance-tab' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2024-05-22 19:55:04 +03:00
commit c679df05d0
32 changed files with 325 additions and 39 deletions

View file

@ -0,0 +1,26 @@
import Timeline from '../timeline/timeline.vue'
const QuotesTimeline = {
created () {
this.$store.commit('clearTimeline', { timeline: 'quotes' })
this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId })
},
components: {
Timeline
},
computed: {
statusId () { return this.$route.params.id },
timeline () { return this.$store.state.statuses.timelines.quotes }
},
watch: {
statusId () {
this.$store.commit('clearTimeline', { timeline: 'quotes' })
this.$store.dispatch('startFetchingTimeline', { timeline: 'quotes', statusId: this.statusId })
}
},
unmounted () {
this.$store.dispatch('stopFetchingTimeline', 'quotes')
}
}
export default QuotesTimeline

View file

@ -0,0 +1,10 @@
<template>
<Timeline
:title="$t('nav.quotes')"
:timeline="timeline"
:timeline-name="'quotes'"
:status-id="statusId"
/>
</template>
<script src='./quotes_timeline.js'></script>

View file

@ -48,6 +48,10 @@ export default {
draftMode: {
type: Boolean,
default: undefined
},
timedApplyMode: {
type: Boolean,
default: false
}
},
inject: {
@ -161,7 +165,11 @@ export default {
case 'admin':
return (k, v) => this.$store.dispatch('pushAdminSetting', { path: k, value: v })
default:
return (k, v) => this.$store.dispatch('setOption', { name: k, value: v })
if (this.timedApplyMode) {
return (k, v) => this.$store.dispatch('setOptionTemporarily', { name: k, value: v })
} else {
return (k, v) => this.$store.dispatch('setOption', { name: k, value: v })
}
}
},
defaultState () {

View file

@ -21,15 +21,23 @@ export default {
unitSet: {
type: String,
default: 'none'
},
step: {
type: Number,
default: 1
},
resetDefault: {
type: Object,
default: null
}
},
computed: {
...Setting.computed,
stateUnit () {
return this.state.replace(/\d+/, '')
return typeof this.state === 'string' ? this.state.replace(/[0-9,.]+/, '') : ''
},
stateValue () {
return this.state.replace(/\D+/, '')
return typeof this.state === 'string' ? this.state.replace(/[^0-9,.]+/, '') : ''
}
},
methods: {
@ -39,10 +47,18 @@ export default {
return this.$t(['settings', 'units', this.unitSet, value].join('.'))
},
updateValue (e) {
this.configSink(this.path, parseInt(e.target.value) + this.stateUnit)
this.configSink(this.path, parseFloat(e.target.value) + this.stateUnit)
},
updateUnit (e) {
this.configSink(this.path, this.stateValue + e.target.value)
let value = this.stateValue
const newUnit = e.target.value
if (this.resetDefault) {
const replaceValue = this.resetDefault[newUnit]
if (replaceValue != null) {
value = replaceValue
}
}
this.configSink(this.path, value + newUnit)
}
}
}

View file

@ -13,7 +13,7 @@
:id="path"
class="input number-input"
type="number"
step="1"
step="step"
:disabled="disabled"
:min="min || 0"
:value="stateValue"

View file

@ -4,6 +4,7 @@ import AsyncComponentError from 'src/components/async_component_error/async_comp
import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
import Popover from '../popover/popover.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep, isEqual } from 'lodash'
import {
@ -53,6 +54,7 @@ const SettingsModal = {
Modal,
Popover,
Checkbox,
ConfirmModal,
SettingsModalUserContent: getResettableAsyncComponent(
() => import('./settings_modal_user_content.vue'),
{
@ -165,6 +167,7 @@ const SettingsModal = {
},
computed: {
currentSaveStateNotice () {
console.log(this.$store.state.interface.settings.currentSaveStateNotice)
return this.$store.state.interface.settings.currentSaveStateNotice
},
modalActivated () {

View file

@ -147,6 +147,18 @@
</span>
</div>
</div>
<teleport to="#modal">
<ConfirmModal
v-if="$store.state.interface.temporaryChangesTimeoutId"
:title="$t('settings.confirm_new_setting')"
:cancel-text="$t('settings.revert')"
:confirm-text="$t('settings.confirm')"
@cancelled="$store.state.interface.temporaryChangesRevert"
@accepted="$store.state.interface.temporaryChangesConfirm"
>
{{ $t('settings.confirm_new_question') }}
</ConfirmModal>
</teleport>
</Modal>
</template>

View file

@ -7,6 +7,7 @@ import FilteringTab from './tabs/filtering_tab.vue'
import SecurityTab from './tabs/security_tab/security_tab.vue'
import ProfileTab from './tabs/profile_tab.vue'
import GeneralTab from './tabs/general_tab.vue'
import AppearanceTab from './tabs/appearance_tab.vue'
import VersionTab from './tabs/version_tab.vue'
import ThemeTab from './tabs/theme_tab/theme_tab.vue'
@ -44,6 +45,7 @@ const SettingsModalContent = {
SecurityTab,
ProfileTab,
GeneralTab,
AppearanceTab,
VersionTab,
ThemeTab
},

View file

@ -21,6 +21,13 @@
>
<ProfileTab />
</div>
<div
:label="$t('settings.appearance')"
icon="paint-brush"
data-tab-name="appearance"
>
<AppearanceTab />
</div>
<div
v-if="isLoggedIn"
:label="$t('settings.security_tab')"

View file

@ -0,0 +1,39 @@
import BooleanSetting from '../helpers/boolean_setting.vue'
import ChoiceSetting from '../helpers/choice_setting.vue'
import IntegerSetting from '../helpers/integer_setting.vue'
import FloatSetting from '../helpers/float_setting.vue'
import UnitSetting from '../helpers/unit_setting.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faGlobe
} from '@fortawesome/free-solid-svg-icons'
library.add(
faGlobe
)
const AppearanceTab = {
data () {
return {}
},
components: {
BooleanSetting,
ChoiceSetting,
IntegerSetting,
FloatSetting,
UnitSetting,
ProfileSettingIndicator
},
computed: {
instanceWallpaperUsed () {
return this.$store.state.instance.background &&
!this.$store.state.users.currentUser.background_image
},
...SharedComputedObject()
}
}
export default AppearanceTab

View file

@ -0,0 +1,71 @@
<template>
<div :label="$t('settings.general')">
<div class="setting-item">
<h2>{{ $t('settings.interface') }}</h2>
<ul class="setting-list">
<li v-if="instanceWallpaperUsed">
<BooleanSetting path="hideInstanceWallpaper">
{{ $t('settings.hide_wallpaper') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="disableStickyHeaders">
{{ $t('settings.disable_sticky_headers') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="showScrollbars">
{{ $t('settings.show_scrollbars') }}
</BooleanSetting>
</li>
<li>
<UnitSetting
path="textSize"
step="0.1"
:units="['px', 'rem']"
:reset-default="{ 'px': 14, 'rem': 1 }"
timed-apply-mode
>
{{ $t('settings.text_size') }}
</UnitSetting>
<div>
<small>
<i18n-t
scope="global"
keypath="settings.text_size_tip"
tag="span"
>
<code>px</code>
<code>rem</code>
</i18n-t>
<br/>
<i18n-t
scope="global"
keypath="settings.text_size_tip2"
tag="span"
>
<code>14px</code>
</i18n-t>
</small>
</div>
</li>
</ul>
</div>
</div>
</template>
<script src="./appearance_tab.js"></script>
<style lang="scss">
.column-settings {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
}
.column-settings .size-label {
display: block;
margin-bottom: 0.5em;
margin-top: 0.5em;
}
</style>

View file

@ -15,11 +15,6 @@
{{ $t('settings.hide_isp') }}
</BooleanSetting>
</li>
<li v-if="instanceWallpaperUsed">
<BooleanSetting path="hideInstanceWallpaper">
{{ $t('settings.hide_wallpaper') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="stopGifs">
{{ $t('settings.stop_gifs') }}
@ -101,16 +96,6 @@
<li>
<h3>{{ $t('settings.columns') }}</h3>
</li>
<li>
<BooleanSetting path="disableStickyHeaders">
{{ $t('settings.disable_sticky_headers') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="showScrollbars">
{{ $t('settings.show_scrollbars') }}
</BooleanSetting>
</li>
<li>
<BooleanSetting path="sidebarRight">
{{ $t('settings.right_sidebar') }}

View file

@ -373,6 +373,9 @@ const Status = {
hidePostStats () {
return this.mergedConfig.hidePostStats
},
shouldDisplayFavsAndRepeats () {
return !this.hidePostStats && this.isFocused && (this.combinedFavsAndRepeatsUsers.length > 0 || this.statusFromGlobalRepository.quotes_count)
},
muteBotStatuses () {
return this.mergedConfig.muteBotStatuses
},
@ -429,6 +432,8 @@ const Status = {
let multiplier = 60 * 1000 // minutes is smallest unit
switch (unit) {
case 'm':
break
case 'h':
multiplier *= 60 // hour
break
case 'd':

View file

@ -374,6 +374,7 @@
font-weight: bolder;
font-size: 1.1em;
line-height: 1em;
color: var(--text);
}
&:hover .stat-title {

View file

@ -484,7 +484,7 @@
<transition name="fade">
<div
v-if="!hidePostStats && isFocused && combinedFavsAndRepeatsUsers.length > 0"
v-if="shouldDisplayFavsAndRepeats"
class="favs-repeated-users"
>
<div class="stats">
@ -512,6 +512,19 @@
</div>
</div>
</UserListPopover>
<router-link
v-if="statusFromGlobalRepository.quotes_count > 0"
:to="{ name: 'quotes', params: { id: status.id } }"
>
<div
class="stat-count"
>
<a class="stat-title">{{ $t('status.quotes') }}</a>
<div class="stat-number">
{{ statusFromGlobalRepository.quotes_count }}
</div>
</div>
</router-link>
<div class="avatar-row">
<AvatarList :users="combinedFavsAndRepeatsUsers" />
</div>

View file

@ -25,6 +25,7 @@ const Timeline = {
'title',
'userId',
'listId',
'statusId',
'tag',
'embedded',
'count',
@ -121,6 +122,7 @@ const Timeline = {
showImmediately,
userId: this.userId,
listId: this.listId,
statusId: this.statusId,
tag: this.tag
})
},
@ -183,6 +185,7 @@ const Timeline = {
showImmediately: true,
userId: this.userId,
listId: this.listId,
statusId: this.statusId,
tag: this.tag
}).then(({ statuses }) => {
if (statuses && statuses.length === 0) {

View file

@ -19,7 +19,8 @@ export const timelineNames = () => {
bookmarks: 'nav.bookmarks',
dms: 'nav.dms',
'public-timeline': 'nav.public_tl',
'public-external-timeline': 'nav.twkn'
'public-external-timeline': 'nav.twkn',
quotes: 'nav.quotes'
}
}