diff --git a/index.html b/index.html index 781b0ba3..5b684594 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,6 @@ Akkoma - diff --git a/src/App.js b/src/App.js index 3e0d0d6f..77b40b62 100644 --- a/src/App.js +++ b/src/App.js @@ -59,7 +59,8 @@ export default { { '-reverse': this.reverseLayout, '-no-sticky-headers': this.noSticky, - '-has-new-post-button': this.newPostButtonShown + '-has-new-post-button': this.newPostButtonShown, + '-wide-timeline': this.widenTimeline }, '-' + this.layoutType ] @@ -93,6 +94,9 @@ export default { newPostButtonShown () { return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile' }, + widenTimeline () { + return this.$store.getters.mergedConfig.widenTimeline + }, showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel }, editingAvailable () { return this.$store.state.instance.editingAvailable }, layoutType () { return this.$store.state.interface.layoutType }, diff --git a/src/App.scss b/src/App.scss index 1d338d15..11d808d6 100644 --- a/src/App.scss +++ b/src/App.scss @@ -172,6 +172,10 @@ nav { background-color: rgba(0, 0, 0, 0.15); background-color: var(--underlay, rgba(0, 0, 0, 0.15)); z-index: -1000; + + .-wide-timeline & { + margin:0 calc(var(--columnGap) / -2); + } } .app-layout { @@ -187,12 +191,17 @@ nav { grid-template-rows: 1fr; box-sizing: border-box; margin: 0 auto; + padding: 0 calc(var(--columnGap) / 2); align-content: flex-start; flex-wrap: wrap; justify-content: center; min-height: 100vh; overflow-x: clip; + &.-wide-timeline { + --maxiColumn: minmax(var(--miniColumn), 1fr); + } + .column { --___columnMargin: var(--columnGap); diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 8687f9ab..90bcdab3 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -183,6 +183,12 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => { copyInstanceOption('renderMisskeyMarkdown') copyInstanceOption('sidebarRight') + if (config.backendCommitUrl) + copyInstanceOption('backendCommitUrl') + + if (config.frontendCommitUrl) + copyInstanceOption('frontendCommitUrl') + return store.dispatch('setTheme', config['theme']) } diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index a0778b6d..58b14967 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -1,4 +1,4 @@ -const MFM_TAGS = ['blur', 'bounce', 'flip', 'font', 'jelly', 'jump', 'rainbow', 'rotate', 'shake', 'sparkle', 'spin', 'tada', 'twitch', 'x2', 'x3', 'x4'] +const MFM_TAGS = ['bg', 'blur', 'bounce', 'center', 'fg', 'flip', 'font', 'jelly', 'jump', 'position', 'rainbow', 'rotate', 'scale', 'shake', 'sparkle', 'spin', 'tada', 'twitch', 'x2', 'x3', 'x4'] .map(tag => ({ displayText: tag, detailText: '$[' + tag + ' ]', replacement: '$[' + tag + ' ]', mfm: true })) /** diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js index 4e1bda55..fa3ec72f 100644 --- a/src/components/gallery/gallery.js +++ b/src/components/gallery/gallery.js @@ -88,10 +88,8 @@ const Gallery = { set(this.sizes, id, { width, height }) }, rowStyle (row) { - if (row.audio) { - return { 'padding-bottom': '25%' } // fixed reduced height for audio - } else if (!row.minimal && !row.grid) { - return { 'padding-bottom': `${(100 / (row.items.length + 0.6))}%` } + if (!row.audio && !row.minimal && !row.grid) { + return { 'aspect-ratio': `1/${(1 / (row.items.length + 0.6))}` } } }, itemStyle (id, row) { diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue index d5500334..d41eccd0 100644 --- a/src/components/gallery/gallery.vue +++ b/src/components/gallery/gallery.vue @@ -96,9 +96,15 @@ .gallery-row { position: relative; - height: 0; width: 100%; flex-grow: 1; + .Status & { + max-height: 30em; + } + + &.-audio { + aspect-ratio: 4/1; // this is terrible, but it's how it was before so I'm not changing it >:( + } &:not(:first-child) { margin-top: 0.5em; diff --git a/src/components/mfa_form/totp_form.vue b/src/components/mfa_form/totp_form.vue index 709eb9b8..17ded4a1 100644 --- a/src/components/mfa_form/totp_form.vue +++ b/src/components/mfa_form/totp_form.vue @@ -18,6 +18,7 @@ diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index e382d8f6..7653ec5c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -336,6 +336,7 @@ const PostStatusForm = { watch: { 'newStatus': { deep: true, + flush: 'sync', handler () { this.statusChanged() } diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index 0da7f3de..eeb5475e 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -121,6 +121,19 @@ export default { } } + const mfmStyleFromDataAttributes = (attributes) => { + // CSS selectors can check if a data-* attribute is true, but can't use other values, so we want to add them to the style attribute + // Here we turn e.g. `{'data-mfm-some': '1deg', 'data-mfm-thing': '5s'}` to "--mfm-some: 1deg;--mfm-thing: 5s;" + // Note that we only add the value to `style` when they contain only letters, numbers, dot, or minus signs + // At the moment of writing, this should be enough for legitimate purposes and reduces the chance of injection by using special characters + // There is a special case for the `color` value, who is provided without `#`, but requires this in the `style` attribute + return Object.keys(attributes).filter( + (key) => key.startsWith('data-mfm-') && attributes[key] !== true && /^[a-zA-Z0-9.\-]*$/.test(attributes[key]) + ).map( + (key) => '--mfm-' + key.substr(9) + (key === 'data-mfm-color' ? ': #' : ': ') + attributes[key] + ';' + ).reduce((a,v) => a+v, '') + } + // Processor to use with html_tree_converter const processItem = (item, index, array, what) => { // Handle text nodes - just add emoji @@ -191,6 +204,15 @@ export default { if (this.handleLinks && attrs?.['class']?.includes?.('h-card')) { return ['', children.map(processItem), ''] } + + let mfm_style = mfmStyleFromDataAttributes(attrs) + if (mfm_style !== '') { + return [ + opener.slice(0,-1) + ' style="' + mfm_style + '">', + children.map(processItem), + closer + ] + } } if (children !== undefined) { diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index 27dab3ec..9a2df9b0 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -69,7 +69,7 @@ const SettingsModal = { this.$store.dispatch('closeSettingsModal') }, logout () { - this.$router.replace('/main/public') + this.$router.replace(this.$store.state.instance.redirectRootNoLogin || '/main/all') this.$store.dispatch('closeSettingsModal') this.$store.dispatch('logout') }, diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index a5f3355c..43b8e4b6 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -159,6 +159,16 @@ {{ $t('settings.show_page_backgrounds') }} +
  • + + {{ $t('settings.center_align_bio') }} + +
  • +
  • + + {{ $t('settings.compact_user_info') }} + +
  • {{ $t('settings.stop_gifs') }} @@ -269,6 +279,11 @@ {{ $t('settings.right_sidebar') }}
  • +
  • + + {{ $t('settings.widen_timeline') }} + +
  • { this.translating = false }) } } } diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss index 78604848..3a878256 100644 --- a/src/components/status_body/status_body.scss +++ b/src/components/status_body/status_body.scss @@ -3,6 +3,7 @@ .StatusBody { display: flex; flex-direction: column; + overflow: hidden; .translation { border: 1px solid var(--accent, $fallback--link); @@ -23,24 +24,6 @@ transition: 0.05s; } - ._mfm_x2_ { - .emoji { - height: 100px; - } - } - - ._mfm_x3_ { - .emoji { - height: 150px; - } - } - - ._mfm_x4_ { - .emoji { - height: 200px; - } - } - .attachments { margin-top: 0.5em; } diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue index 882b38c5..068c6c1b 100644 --- a/src/components/status_body/status_body.vue +++ b/src/components/status_body/status_body.vue @@ -1,7 +1,7 @@ +