Merge remote-tracking branch 'origin/develop' into sss-objects
This commit is contained in:
commit
76616461e9
130 changed files with 1129 additions and 1205 deletions
|
|
@ -56,7 +56,7 @@
|
|||
.post-textarea {
|
||||
resize: vertical;
|
||||
height: 10em;
|
||||
overflow: none;
|
||||
overflow: visible;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,7 @@
|
|||
.outgoing {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-content: end;
|
||||
justify-content: flex-end;
|
||||
place-content: end flex-end;
|
||||
|
||||
.chat-message-inner {
|
||||
align-items: flex-end;
|
||||
|
|
|
|||
|
|
@ -190,20 +190,15 @@ export default {
|
|||
|
||||
.header {
|
||||
grid-area: header;
|
||||
justify-self: center;
|
||||
align-self: baseline;
|
||||
place-self: baseline center;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.invalid-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
place-items: center center;
|
||||
background-color: rgba(100 0 0 / 50%);
|
||||
|
||||
.alert {
|
||||
|
|
@ -214,7 +209,7 @@ export default {
|
|||
.assists {
|
||||
grid-area: assists;
|
||||
display: grid;
|
||||
grid-auto-flow: rows;
|
||||
grid-auto-flow: row;
|
||||
grid-auto-rows: 2em;
|
||||
grid-gap: 0.5em;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -322,10 +322,7 @@
|
|||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc(var(--___margin) * -1);
|
||||
bottom: calc(var(--___margin) * -1);
|
||||
left: calc(var(--___margin) * -1);
|
||||
right: calc(var(--___margin) * -1);
|
||||
inset: calc(var(--___margin) * -1);
|
||||
background: var(--background);
|
||||
backdrop-filter: var(--__panel-backdrop-filter);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
transition-timing-function: ease-out;
|
||||
transition-duration: 100ms;
|
||||
|
||||
@media all and (min-width: 800px) {
|
||||
@media all and (width >= 800px) {
|
||||
/* stylelint-disable-next-line declaration-no-important */
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
|
@ -70,10 +70,7 @@
|
|||
mask-size: contain;
|
||||
background-color: var(--text);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
|
|
|
|||
|
|
@ -29,14 +29,11 @@
|
|||
// TODO: unify with other modals.
|
||||
.dark-overlay {
|
||||
&::before {
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
content: " ";
|
||||
display: block;
|
||||
cursor: default;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background: rgb(27 31 35 / 50%);
|
||||
z-index: 2000;
|
||||
}
|
||||
|
|
@ -45,13 +42,9 @@
|
|||
.dialog-container {
|
||||
display: grid;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
place-items: center center;
|
||||
}
|
||||
|
||||
.dialog-modal.panel {
|
||||
|
|
@ -98,8 +91,7 @@
|
|||
#modal.-mobile {
|
||||
.dialog-container {
|
||||
justify-content: stretch;
|
||||
align-items: end;
|
||||
justify-items: stretch;
|
||||
place-items: end stretch;
|
||||
|
||||
&.-center-mobile {
|
||||
align-items: center;
|
||||
|
|
@ -114,7 +106,6 @@
|
|||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-columns: none;
|
||||
grid-auto-rows: auto;
|
||||
grid-auto-flow: row dense;
|
||||
|
||||
|
|
|
|||
|
|
@ -135,8 +135,7 @@
|
|||
.poll-indicator-container {
|
||||
border-radius: var(--roundness);
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
place-items: center center;
|
||||
align-self: start;
|
||||
height: 0;
|
||||
padding-bottom: 62.5%;
|
||||
|
|
@ -147,13 +146,9 @@
|
|||
box-sizing: border-box;
|
||||
border: 1px solid var(--border);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
place-items: center center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,10 +159,7 @@
|
|||
opacity: 0;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
|
||||
/* DEBUG STUFF */
|
||||
|
|
|
|||
|
|
@ -64,8 +64,7 @@
|
|||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
overflow: auto hidden;
|
||||
}
|
||||
|
||||
.additional-tabs {
|
||||
|
|
@ -153,7 +152,13 @@
|
|||
transition: mask-size 150ms;
|
||||
mask-size: 100% 20px, 100% 20px, auto;
|
||||
// Autoprefixed seem to ignore this one, and also syntax is different
|
||||
/* stylelint-disable mask-composite */
|
||||
/* stylelint-disable declaration-property-value-no-unknown */
|
||||
|
||||
/* TODO check if this is still needed */
|
||||
mask-composite: xor;
|
||||
/* stylelint-enable declaration-property-value-no-unknown */
|
||||
/* stylelint-enable mask-composite */
|
||||
mask-composite: exclude;
|
||||
|
||||
&.scrolled {
|
||||
|
|
@ -197,8 +202,7 @@
|
|||
&-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--__amount), 1fr);
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
place-items: center center;
|
||||
justify-content: center;
|
||||
grid-template-rows: repeat(1, auto);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
.hidden {
|
||||
display: none;
|
||||
visibility: "hidden";
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -101,10 +101,7 @@
|
|||
|
||||
.gallery-row-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-content: stretch;
|
||||
|
|
@ -160,7 +157,13 @@
|
|||
linear-gradient(to top, white, white);
|
||||
|
||||
/* Autoprefixed seem to ignore this one, and also syntax is different */
|
||||
/* stylelint-disable mask-composite */
|
||||
/* stylelint-disable declaration-property-value-no-unknown */
|
||||
|
||||
/* TODO check if this is still needed */
|
||||
mask-composite: xor;
|
||||
/* stylelint-enable declaration-property-value-no-unknown */
|
||||
/* stylelint-enable mask-composite */
|
||||
mask-composite: exclude;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import Cropper from 'cropperjs'
|
||||
import 'cropperjs/dist/cropper.css'
|
||||
import 'cropperjs' // This adds all of the cropperjs's components into DOM
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faCircleNotch
|
||||
|
|
@ -19,19 +18,6 @@ const ImageCropper = {
|
|||
type: Function,
|
||||
required: true
|
||||
},
|
||||
cropperOptions: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
aspectRatio: 1,
|
||||
autoCropArea: 1,
|
||||
viewMode: 1,
|
||||
movable: false,
|
||||
zoomable: false,
|
||||
guides: false
|
||||
}
|
||||
}
|
||||
},
|
||||
mimes: {
|
||||
type: String,
|
||||
default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon'
|
||||
|
|
@ -48,7 +34,6 @@ const ImageCropper = {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
cropper: undefined,
|
||||
dataUrl: undefined,
|
||||
filename: undefined,
|
||||
submitting: false
|
||||
|
|
@ -67,27 +52,30 @@ const ImageCropper = {
|
|||
},
|
||||
methods: {
|
||||
destroy () {
|
||||
if (this.cropper) {
|
||||
this.cropper.destroy()
|
||||
}
|
||||
this.$refs.input.value = ''
|
||||
this.dataUrl = undefined
|
||||
this.$emit('close')
|
||||
},
|
||||
submit (cropping = true) {
|
||||
this.submitting = true
|
||||
this.submitHandler(cropping && this.cropper, this.file)
|
||||
.then(() => this.destroy())
|
||||
.finally(() => {
|
||||
this.submitting = false
|
||||
})
|
||||
|
||||
let cropperPromise
|
||||
if (cropping) {
|
||||
cropperPromise = this.$refs.cropperSelection.$toCanvas()
|
||||
} else {
|
||||
cropperPromise = Promise.resolve()
|
||||
}
|
||||
cropperPromise.then(canvas => {
|
||||
this.submitHandler(canvas, this.file)
|
||||
.then(() => this.destroy())
|
||||
.finally(() => {
|
||||
this.submitting = false
|
||||
})
|
||||
})
|
||||
},
|
||||
pickImage () {
|
||||
this.$refs.input.click()
|
||||
},
|
||||
createCropper () {
|
||||
this.cropper = new Cropper(this.$refs.img, this.cropperOptions)
|
||||
},
|
||||
getTriggerDOM () {
|
||||
return typeof this.trigger === 'object' ? this.trigger : document.querySelector(this.trigger)
|
||||
},
|
||||
|
|
@ -103,6 +91,29 @@ const ImageCropper = {
|
|||
reader.readAsDataURL(this.file)
|
||||
this.$emit('changed', this.file, reader)
|
||||
}
|
||||
},
|
||||
inSelection(selection, maxSelection) {
|
||||
return (
|
||||
selection.x >= maxSelection.x
|
||||
&& selection.y >= maxSelection.y
|
||||
&& (selection.x + selection.width) <= (maxSelection.x + maxSelection.width)
|
||||
&& (selection.y + selection.height) <= (maxSelection.y + maxSelection.height)
|
||||
)
|
||||
},
|
||||
onCropperSelectionChange(event) {
|
||||
const cropperCanvas = this.$refs.cropperCanvas
|
||||
const cropperCanvasRect = cropperCanvas.getBoundingClientRect()
|
||||
const selection = event.detail
|
||||
const maxSelection = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: cropperCanvasRect.width,
|
||||
height: cropperCanvasRect.height,
|
||||
}
|
||||
|
||||
if (!this.inSelection(selection, maxSelection)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,43 @@
|
|||
<template>
|
||||
<div class="image-cropper">
|
||||
<div v-if="dataUrl">
|
||||
<div class="image-cropper-image-container">
|
||||
<img
|
||||
ref="img"
|
||||
<cropper-canvas
|
||||
background
|
||||
class="image-cropper-canvas"
|
||||
ref="cropperCanvas"
|
||||
height="25em"
|
||||
>
|
||||
<cropper-image
|
||||
:src="dataUrl"
|
||||
alt=""
|
||||
@load.stop="createCropper"
|
||||
alt="Picture"
|
||||
ref="cropperImage"
|
||||
class="image-cropper-image"
|
||||
translatable
|
||||
scalable
|
||||
/>
|
||||
<cropper-shade hidden />
|
||||
<cropper-handle action="select" plain />
|
||||
<cropper-selection
|
||||
ref="cropperSelection"
|
||||
initial-coverage="1"
|
||||
aspect-ratio="1"
|
||||
movable
|
||||
resizable
|
||||
@change="onCropperSelectionChange"
|
||||
>
|
||||
</div>
|
||||
<cropper-grid role="grid" covered></cropper-grid>
|
||||
<cropper-crosshair centered></cropper-crosshair>
|
||||
<cropper-handle action="move" theme-color="rgba(255, 255, 255, 0.35)"></cropper-handle>
|
||||
<cropper-handle action="n-resize"></cropper-handle>
|
||||
<cropper-handle action="e-resize"></cropper-handle>
|
||||
<cropper-handle action="s-resize"></cropper-handle>
|
||||
<cropper-handle action="w-resize"></cropper-handle>
|
||||
<cropper-handle action="ne-resize"></cropper-handle>
|
||||
<cropper-handle action="nw-resize"></cropper-handle>
|
||||
<cropper-handle action="se-resize"></cropper-handle>
|
||||
<cropper-handle action="sw-resize"></cropper-handle>
|
||||
</cropper-selection>
|
||||
</cropper-canvas>
|
||||
<div class="image-cropper-buttons-wrapper">
|
||||
<button
|
||||
class="button-default btn"
|
||||
|
|
@ -55,20 +84,18 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
&-image-container {
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
&-canvas {
|
||||
height: 25em;
|
||||
width: 25em;
|
||||
}
|
||||
|
||||
&-buttons-wrapper {
|
||||
margin-top: 10px;
|
||||
display: grid;
|
||||
grid-gap: 0.5em;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
|
||||
button {
|
||||
margin-top: 5px;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,10 +68,12 @@
|
|||
margin: 0.5em 0 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-word;
|
||||
word-break: break-all;
|
||||
line-height: 1.2em;
|
||||
// cap description at 3 lines, the 1px is to clean up some stray pixels
|
||||
// TODO: fancier fade-out at the bottom to show off that it's too long?
|
||||
|
||||
/* cap description at 3 lines, the 1px is to clean up some stray pixels
|
||||
TODO: fancier fade-out at the bottom to show off that it's too long?
|
||||
*/
|
||||
max-height: calc(1.2em * 3 - 1px);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import mfaApi from '../../services/new_api/mfa.js'
|
||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { mapStores } from 'pinia'
|
||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faTimes
|
||||
|
|
@ -18,17 +20,24 @@ export default {
|
|||
...mapGetters({
|
||||
authSettings: 'authFlow/settings'
|
||||
}),
|
||||
...mapStores(useOAuthStore),
|
||||
...mapState({
|
||||
instance: 'instance',
|
||||
oauth: 'oauth'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('authFlow', ['requireTOTP', 'abortMFA']),
|
||||
...mapActions({ login: 'authFlow/login' }),
|
||||
clearError () { this.error = false },
|
||||
|
||||
focusOnCodeInput () {
|
||||
const codeInput = this.$refs.codeInput
|
||||
codeInput.focus()
|
||||
codeInput.setSelectionRange(0, codeInput.value.length)
|
||||
},
|
||||
|
||||
submit () {
|
||||
const { clientId, clientSecret } = this.oauth
|
||||
const { clientId, clientSecret } = this.oauthStore
|
||||
|
||||
const data = {
|
||||
clientId,
|
||||
|
|
@ -42,6 +51,7 @@ export default {
|
|||
if (result.error) {
|
||||
this.error = result.error
|
||||
this.code = null
|
||||
this.focusOnCodeInput()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="login panel panel-default">
|
||||
<div class="login-panel panel panel-default">
|
||||
<!-- Default panel contents -->
|
||||
|
||||
<div class="panel-heading">
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
<label for="code">{{ $t('login.recovery_code') }}</label>
|
||||
<input
|
||||
id="code"
|
||||
ref="codeInput"
|
||||
v-model="code"
|
||||
class="input form-control"
|
||||
>
|
||||
|
|
@ -71,4 +72,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./recovery_form.js"></script>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import mfaApi from '../../services/new_api/mfa.js'
|
||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { mapStores } from 'pinia'
|
||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faTimes
|
||||
|
|
@ -18,17 +20,24 @@ export default {
|
|||
...mapGetters({
|
||||
authSettings: 'authFlow/settings'
|
||||
}),
|
||||
...mapStores(useOAuthStore),
|
||||
...mapState({
|
||||
instance: 'instance',
|
||||
oauth: 'oauth'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapMutations('authFlow', ['requireRecovery', 'abortMFA']),
|
||||
...mapActions({ login: 'authFlow/login' }),
|
||||
clearError () { this.error = false },
|
||||
|
||||
focusOnCodeInput () {
|
||||
const codeInput = this.$refs.codeInput
|
||||
codeInput.focus()
|
||||
codeInput.setSelectionRange(0, codeInput.value.length)
|
||||
},
|
||||
|
||||
submit () {
|
||||
const { clientId, clientSecret } = this.oauth
|
||||
const { clientId, clientSecret } = this.oauthStore
|
||||
|
||||
const data = {
|
||||
clientId,
|
||||
|
|
@ -42,6 +51,7 @@ export default {
|
|||
if (result.error) {
|
||||
this.error = result.error
|
||||
this.code = null
|
||||
this.focusOnCodeInput()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="login panel panel-default">
|
||||
<div class="login-panel panel panel-default">
|
||||
<!-- Default panel contents -->
|
||||
|
||||
<div class="panel-heading">
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
</label>
|
||||
<input
|
||||
id="code"
|
||||
ref="codeInput"
|
||||
v-model="code"
|
||||
class="input form-control"
|
||||
>
|
||||
|
|
@ -74,4 +75,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./totp_form.js"></script>
|
||||
|
|
|
|||
|
|
@ -220,8 +220,7 @@
|
|||
margin-top: 3.5em;
|
||||
width: 100vw;
|
||||
height: calc(100vh - var(--navbar-height));
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
overflow: hidden scroll;
|
||||
|
||||
.notifications {
|
||||
padding: 0;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 801px) {
|
||||
@media all and (width >= 801px) {
|
||||
.new-status-button:not(.always-show) {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,10 +41,7 @@ export default {
|
|||
.modal-view {
|
||||
z-index: var(--ZI_modals);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
border-bottom: 1px solid;
|
||||
border-color: var(--border);
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
word-break: break-all;
|
||||
|
||||
&.Status {
|
||||
/* stylelint-disable-next-line declaration-no-important */
|
||||
|
|
|
|||
|
|
@ -13,10 +13,7 @@
|
|||
|
||||
.notification-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
align-items: center;
|
||||
padding: 0.1em 0.25em;
|
||||
z-index: 1;
|
||||
word-break: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.result-percentage {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,7 @@
|
|||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
bottom: -1px;
|
||||
left: -1px;
|
||||
right: -1px;
|
||||
z-index: -1px;
|
||||
inset: -1px;
|
||||
box-shadow: var(--_shadow);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@
|
|||
margin: 0.6em;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
.registration-form .container {
|
||||
flex-direction: column-reverse;
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
.search-nav-heading {
|
||||
.tab-switcher .tabs .tab-wrapper {
|
||||
display: block;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
.emoji-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1em 1em;
|
||||
gap: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,15 +13,11 @@
|
|||
// fix buttons showing through
|
||||
z-index: 2;
|
||||
opacity: 0.9;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
dd {
|
||||
text-overflow: ellipsis;
|
||||
word-wrap: nowrap;
|
||||
white-space: nowrap;
|
||||
overflow-x: hidden;
|
||||
max-width: 10em;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
max-width: 90vw;
|
||||
height: 90vh;
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
max-width: 100vw;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
> li {
|
||||
margin: 1em 0;
|
||||
line-height: 1.5em;
|
||||
vertical-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&.two-column {
|
||||
|
|
@ -105,7 +105,7 @@
|
|||
*/
|
||||
transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
/* For mobile, the modal takes 100% of the available screen.
|
||||
This ensures the minimized modal is always 50px above the browser bottom
|
||||
bar regardless of whether or not it is visible.
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@
|
|||
|
||||
.palettes-container {
|
||||
height: 15em;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden auto;
|
||||
scrollbar-gutter: stable;
|
||||
border-radius: var(--roundness);
|
||||
border: 1px solid var(--border);
|
||||
|
|
@ -112,8 +111,7 @@
|
|||
flex-wrap: wrap;
|
||||
margin: -0.5em 0;
|
||||
height: 25em;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overflow: hidden auto;
|
||||
scrollbar-gutter: stable;
|
||||
border-radius: var(--roundness);
|
||||
border: 1px solid var(--border);
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ const ProfileTab = {
|
|||
this.submitBackground('')
|
||||
}
|
||||
},
|
||||
submitAvatar (cropper, file) {
|
||||
submitAvatar (canvas, file) {
|
||||
const that = this
|
||||
return new Promise((resolve, reject) => {
|
||||
function updateAvatar (avatar, avatarName) {
|
||||
|
|
@ -232,8 +232,8 @@ const ProfileTab = {
|
|||
})
|
||||
}
|
||||
|
||||
if (cropper) {
|
||||
cropper.getCroppedCanvas().toBlob((data) => updateAvatar(data, file.name), file.type)
|
||||
if (canvas) {
|
||||
canvas.toBlob((data) => updateAvatar(data, file.name), file.type)
|
||||
} else {
|
||||
updateAvatar(file, file.name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@
|
|||
.state-selector,
|
||||
.variant-selector {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr minmax(1fr, 10em);
|
||||
grid-template-columns: 1fr minmax(10em, 1fr);
|
||||
grid-template-rows: auto;
|
||||
grid-auto-flow: column;
|
||||
grid-gap: 0.5em;
|
||||
|
|
|
|||
|
|
@ -241,10 +241,7 @@ export default {
|
|||
|
||||
.underlay-preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
inset: 0 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -112,8 +112,7 @@
|
|||
grid-area: preview;
|
||||
min-width: 25em;
|
||||
margin-left: 0.125em;
|
||||
align-self: start;
|
||||
justify-self: center;
|
||||
place-self: start center;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,8 +107,7 @@
|
|||
}
|
||||
|
||||
.shout-window {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden auto;
|
||||
max-height: 20em;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
min-width: 0;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
word-break: break-all;
|
||||
|
||||
&:hover {
|
||||
--_still-image-img-visibility: visible;
|
||||
|
|
@ -364,7 +364,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
.repeater-avatar {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
|
@ -374,7 +374,6 @@
|
|||
height: 40px;
|
||||
|
||||
// TODO define those other way somehow?
|
||||
// stylelint-disable rscss/class-format
|
||||
&.-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ export default {
|
|||
}
|
||||
},
|
||||
doActionWrap (button, close = () => {}) {
|
||||
if (this.button.interactive ? !this.button.interactive(this.funcArg) : false) return
|
||||
this.$emit('interacted')
|
||||
if (button.name === 'emoji') {
|
||||
this.$refs.picker.showPicker()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
:title="$t(button.label(funcArg))"
|
||||
target="_blank"
|
||||
:tabindex="0"
|
||||
:disabled="buttonClass.disabled"
|
||||
:disabled="button.interactive ? !button.interactive(funcArg) : false"
|
||||
:href="getComponent(button) == 'a' ? button.link?.(funcArg) || remoteInteractionLink : undefined"
|
||||
@click="doActionWrap(button, outerClose)"
|
||||
>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
:style="{ '--fa-animation-duration': '750ms' }"
|
||||
fixed-width
|
||||
/>
|
||||
<template v-if="!buttonClass.disabled && button.toggleable?.(funcArg) && button.active">
|
||||
<template v-if="!buttonClass.disabled && (!button.interactive || button?.interactive(funcArg)) && button.toggleable?.(funcArg) && button.active">
|
||||
<FAIcon
|
||||
v-if="button.active(funcArg)"
|
||||
class="active-marker"
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ export const BUTTONS = [{
|
|||
label: ({ status }) => status.repeated
|
||||
? 'tool_tip.unrepeat'
|
||||
: 'tool_tip.repeat',
|
||||
icon ({ status }) {
|
||||
if (PRIVATE_SCOPES.has(status.visibility)) {
|
||||
icon ({ status, currentUser }) {
|
||||
if (currentUser.id !== status.user.id && PRIVATE_SCOPES.has(status.visibility)) {
|
||||
return 'lock'
|
||||
}
|
||||
return 'retweet'
|
||||
|
|
@ -40,7 +40,7 @@ export const BUTTONS = [{
|
|||
active: ({ status }) => status.repeated,
|
||||
counter: ({ status }) => status.repeat_num,
|
||||
anonLink: true,
|
||||
interactive: ({ status, loggedIn }) => loggedIn && !PRIVATE_SCOPES.has(status.visibility),
|
||||
interactive: ({ status, currentUser }) => !!currentUser && (currentUser.id === status.user.id || !PRIVATE_SCOPES.has(status.visibility)),
|
||||
toggleable: true,
|
||||
confirm: ({ status, getters }) => !status.repeated && getters.mergedConfig.modalOnRepeat,
|
||||
confirmStrings: {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
word-break: break-all;
|
||||
line-height: var(--post-line-height);
|
||||
}
|
||||
|
||||
|
|
@ -60,8 +60,7 @@
|
|||
&.-tall-status {
|
||||
position: relative;
|
||||
height: 220px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
|
||||
.media-body {
|
||||
|
|
@ -71,7 +70,13 @@
|
|||
linear-gradient(to top, white, white);
|
||||
|
||||
/* Autoprefixed seem to ignore this one, and also syntax is different */
|
||||
/* stylelint-disable mask-composite */
|
||||
/* stylelint-disable declaration-property-value-no-unknown */
|
||||
|
||||
/* TODO check if this is still needed */
|
||||
mask-composite: xor;
|
||||
/* stylelint-enable declaration-property-value-no-unknown */
|
||||
/* stylelint-enable mask-composite */
|
||||
mask-composite: exclude;
|
||||
}
|
||||
}
|
||||
|
|
@ -110,7 +115,7 @@
|
|||
}
|
||||
|
||||
&.-compact {
|
||||
align-items: top;
|
||||
align-items: start;
|
||||
flex-direction: row;
|
||||
|
||||
--emoji-size: calc(var(--emojiSize, 32px) / 2);
|
||||
|
|
@ -131,7 +136,13 @@
|
|||
mask-image: linear-gradient(to bottom, white 2em, transparent 3em);
|
||||
|
||||
/* Autoprefixed seem to ignore this one, and also syntax is different */
|
||||
/* stylelint-disable mask-composite */
|
||||
/* stylelint-disable declaration-property-value-no-unknown */
|
||||
|
||||
/* TODO check if this is still needed */
|
||||
mask-composite: xor;
|
||||
/* stylelint-enable declaration-property-value-no-unknown */
|
||||
/* stylelint-enable mask-composite */
|
||||
mask-composite: exclude;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,16 @@
|
|||
:class="{ 'menu-checkbox-checked': status.bookmark_folder_id == folder.id }"
|
||||
/>
|
||||
<StillImage
|
||||
v-if="folder.emoji_url"
|
||||
:src="folder.emoji_url"
|
||||
class="emoji"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="iconLetter fa-scale-110 fa-old-padding"
|
||||
>
|
||||
{{ folder.name[0] }}
|
||||
</span>
|
||||
{{ ' ' + folder.name }}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -37,10 +37,7 @@
|
|||
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
|
||||
> .tabs {
|
||||
width: 100%;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
overflow: auto hidden;
|
||||
padding-top: 5px;
|
||||
flex-direction: row;
|
||||
flex: 0 0 auto;
|
||||
|
|
@ -44,7 +43,7 @@
|
|||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
padding-bottom: 99px;
|
||||
margin-bottom: 6px - 99px;
|
||||
margin-bottom: calc(6px - 99px);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +55,7 @@
|
|||
&.side-tabs {
|
||||
flex-direction: row;
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
|
|
@ -66,8 +65,7 @@
|
|||
|
||||
> .tabs {
|
||||
flex: 0 0 auto;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden auto;
|
||||
flex-direction: column;
|
||||
|
||||
&::after,
|
||||
|
|
@ -92,7 +90,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
min-width: 4em;
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +131,7 @@
|
|||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
padding-left: 0.25em;
|
||||
padding-right: calc(0.25em + 200px);
|
||||
margin-right: calc(0.25em - 200px);
|
||||
|
|
@ -244,7 +242,7 @@
|
|||
margin-bottom: 0.25em;
|
||||
border-bottom: 1px solid var(--border);
|
||||
|
||||
@media all and (min-width: 800px) {
|
||||
@media all and (width >= 800px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
padding-left: 1em;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
@media all and (width <= 800px) {
|
||||
/* For mobile, the modal takes 100% of the available screen.
|
||||
This ensures the minimized modal is always 50px above the browser
|
||||
bottom bar regardless of whether or not it is visible.
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
width: 100vw;
|
||||
}
|
||||
|
||||
@media all and (max-height: 600px) {
|
||||
@media all and (height <= 600px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,15 +21,18 @@
|
|||
|
||||
.background-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
mask:
|
||||
linear-gradient(to top, white, transparent) bottom no-repeat,
|
||||
linear-gradient(to top, white, white);
|
||||
// Autoprefixer seem to ignore this one, and also syntax is different
|
||||
/* stylelint-disable mask-composite */
|
||||
/* stylelint-disable declaration-property-value-no-unknown */
|
||||
|
||||
/* TODO check if this is still needed */
|
||||
mask-composite: xor;
|
||||
/* stylelint-enable declaration-property-value-no-unknown */
|
||||
/* stylelint-enable mask-composite */
|
||||
mask-composite: exclude;
|
||||
background-size: cover;
|
||||
mask-size: 100% 60%;
|
||||
|
|
@ -125,10 +128,7 @@
|
|||
|
||||
&.-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
background-color: rgb(0 0 0 / 30%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
}
|
||||
|
||||
.bottom-line {
|
||||
font-weight: light;
|
||||
font-weight: lighter;
|
||||
font-size: 1.1em;
|
||||
align-items: baseline;
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@
|
|||
.userlist-placeholder {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: middle;
|
||||
align-items: center;
|
||||
padding: 2em;
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +232,7 @@
|
|||
.panel-body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: middle;
|
||||
align-items: center;
|
||||
padding: 7em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 801px) {
|
||||
@media all and (width >= 801px) {
|
||||
.panel-body {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue