Merge remote-tracking branch 'origin/develop' into timed-user-mutes
This commit is contained in:
commit
385f921c41
72 changed files with 1336 additions and 851 deletions
|
|
@ -11,6 +11,11 @@ const getSWMessagesAsText = async () => {
|
||||||
}
|
}
|
||||||
const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)))
|
const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)))
|
||||||
|
|
||||||
|
const swEnvName = 'virtual:pleroma-fe/service_worker_env'
|
||||||
|
const swEnvNameResolved = '\0' + swEnvName
|
||||||
|
const getDevSwEnv = () => `self.serviceWorkerOption = { assets: [] };`
|
||||||
|
const getProdSwEnv = ({ assets }) => `self.serviceWorkerOption = { assets: ${JSON.stringify(assets)} };`
|
||||||
|
|
||||||
export const devSwPlugin = ({
|
export const devSwPlugin = ({
|
||||||
swSrc,
|
swSrc,
|
||||||
swDest,
|
swDest,
|
||||||
|
|
@ -32,12 +37,16 @@ export const devSwPlugin = ({
|
||||||
const name = id.startsWith('/') ? id.slice(1) : id
|
const name = id.startsWith('/') ? id.slice(1) : id
|
||||||
if (name === swDest) {
|
if (name === swDest) {
|
||||||
return swFullSrc
|
return swFullSrc
|
||||||
|
} else if (name === swEnvName) {
|
||||||
|
return swEnvNameResolved
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
async load (id) {
|
async load (id) {
|
||||||
if (id === swFullSrc) {
|
if (id === swFullSrc) {
|
||||||
return readFile(swFullSrc, 'utf-8')
|
return readFile(swFullSrc, 'utf-8')
|
||||||
|
} else if (id === swEnvNameResolved) {
|
||||||
|
return getDevSwEnv()
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
|
|
@ -79,6 +88,21 @@ export const devSwPlugin = ({
|
||||||
contents: await getSWMessagesAsText()
|
contents: await getSWMessagesAsText()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
name: 'sw-env',
|
||||||
|
setup (b) {
|
||||||
|
b.onResolve(
|
||||||
|
{ filter: new RegExp('^' + swEnvName + '$') },
|
||||||
|
args => ({
|
||||||
|
path: args.path,
|
||||||
|
namespace: 'sw-env'
|
||||||
|
}))
|
||||||
|
b.onLoad(
|
||||||
|
{ filter: /.*/, namespace: 'sw-env' },
|
||||||
|
() => ({
|
||||||
|
contents: getDevSwEnv()
|
||||||
|
}))
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
const text = res.outputFiles[0].text
|
const text = res.outputFiles[0].text
|
||||||
|
|
@ -126,6 +150,30 @@ export const buildSwPlugin = ({
|
||||||
configFile: false
|
configFile: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
generateBundle: {
|
||||||
|
order: 'post',
|
||||||
|
sequential: true,
|
||||||
|
async handler (_, bundle) {
|
||||||
|
const assets = Object.keys(bundle)
|
||||||
|
.filter(name => !/\.map$/.test(name))
|
||||||
|
.map(name => '/' + name)
|
||||||
|
config.plugins.push({
|
||||||
|
name: 'build-sw-env-plugin',
|
||||||
|
resolveId (id) {
|
||||||
|
if (id === swEnvName) {
|
||||||
|
return swEnvNameResolved
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
load (id) {
|
||||||
|
if (id === swEnvNameResolved) {
|
||||||
|
return getProdSwEnv({ assets })
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
closeBundle: {
|
closeBundle: {
|
||||||
order: 'post',
|
order: 'post',
|
||||||
sequential: true,
|
sequential: true,
|
||||||
|
|
|
||||||
1
changelog.d/action-button-extra-counter.add
Normal file
1
changelog.d/action-button-extra-counter.add
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Display counter for status action buttons when they are on the menu
|
||||||
0
changelog.d/akkoftermapth.skip
Normal file
0
changelog.d/akkoftermapth.skip
Normal file
1
changelog.d/akkoma-sharkey-net-support.add
Normal file
1
changelog.d/akkoma-sharkey-net-support.add
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Added support for Akkoma and IceShrimp.NET backend
|
||||||
0
changelog.d/akkoma.skip
Normal file
0
changelog.d/akkoma.skip
Normal file
2
changelog.d/arithmetic-blend.add
Normal file
2
changelog.d/arithmetic-blend.add
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Add arithmetic blend ISS function
|
||||||
|
|
||||||
1
changelog.d/bookmark-button-align.fix
Normal file
1
changelog.d/bookmark-button-align.fix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Fix bookmark button alignment in the extra actions menu
|
||||||
1
changelog.d/csp.add
Normal file
1
changelog.d/csp.add
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Compatibility with stricter CSP (Akkoma backend)
|
||||||
0
changelog.d/migrate-auth-flow-pinia.skip
Normal file
0
changelog.d/migrate-auth-flow-pinia.skip
Normal file
0
changelog.d/small-fixes.skip
Normal file
0
changelog.d/small-fixes.skip
Normal file
1
changelog.d/sw-cache-assets.add
Normal file
1
changelog.d/sw-cache-assets.add
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Cache assets and emojis with service worker
|
||||||
1
changelog.d/unify-show-hide-buttons.add
Normal file
1
changelog.d/unify-show-hide-buttons.add
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Unify show/hide content buttons
|
||||||
0
changelog.d/zoomlag.skip
Normal file
0
changelog.d/zoomlag.skip
Normal file
130
index.html
130
index.html
|
|
@ -5,138 +5,16 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
|
||||||
<link rel="preload" href="/static/config.json" as="fetch" crossorigin />
|
<link rel="preload" href="/static/config.json" as="fetch" crossorigin />
|
||||||
<link rel="preload" href="/api/pleroma/frontend_configurations" as="fetch" crossorigin />
|
<link rel="preload" href="/api/pleroma/frontend_configurations" as="fetch" crossorigin />
|
||||||
|
<link rel="preload" href="/nodeinfo/2.0.json" as="fetch" crossorigin />
|
||||||
<link rel="preload" href="/nodeinfo/2.1.json" as="fetch" crossorigin />
|
<link rel="preload" href="/nodeinfo/2.1.json" as="fetch" crossorigin />
|
||||||
<link rel="preload" href="/api/v1/instance" as="fetch" crossorigin />
|
<link rel="preload" href="/api/v1/instance" as="fetch" crossorigin />
|
||||||
<link rel="preload" href="/static/pleromatan_apology_fox_small.webp" as="image" />
|
<link rel="preload" href="/static/pleromatan_apology_fox_small.webp" as="image" />
|
||||||
<!-- putting styles here to avoid having to wait for styles to load up -->
|
<!-- putting styles here to avoid having to wait for styles to load up -->
|
||||||
<style id="splashscreen">
|
<link rel="stylesheet" id="splashscreen" href="/static/splash.css" />
|
||||||
#splash {
|
<link rel="stylesheet" id="custom-styles-holder" type="text/css" href="/static/empty.css" />
|
||||||
--scale: 1;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: auto;
|
|
||||||
grid-template-columns: auto;
|
|
||||||
align-content: center;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
justify-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
background: #0f161e;
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: #b9b9ba;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 9999;
|
|
||||||
font-size: calc(1vw + 1vh + 1vmin);
|
|
||||||
}
|
|
||||||
|
|
||||||
#splash-credit {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 14px;
|
|
||||||
bottom: 16px;
|
|
||||||
right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#splash-container {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mascot-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
perspective: 60em;
|
|
||||||
perspective-origin: 0 -15em;
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mascot {
|
|
||||||
width: calc(10em * var(--scale));
|
|
||||||
height: calc(10em * var(--scale));
|
|
||||||
object-fit: contain;
|
|
||||||
object-position: bottom;
|
|
||||||
transform: translateZ(-2em);
|
|
||||||
}
|
|
||||||
|
|
||||||
#throbber {
|
|
||||||
display: grid;
|
|
||||||
width: calc(5em * 0.5 * var(--scale));
|
|
||||||
height: calc(8em * 0.5 * var(--scale));
|
|
||||||
margin-left: 4.1em;
|
|
||||||
z-index: 2;
|
|
||||||
grid-template-rows: repeat(8, 1fr);
|
|
||||||
grid-template-columns: repeat(5, 1fr);
|
|
||||||
grid-template-areas: "P P . L L"
|
|
||||||
"P P . L L"
|
|
||||||
"P P . L L"
|
|
||||||
"P P . L L"
|
|
||||||
"P P . . ."
|
|
||||||
"P P . . ."
|
|
||||||
"P P . E E"
|
|
||||||
"P P . E E";
|
|
||||||
|
|
||||||
--logoChunkSize: calc(2em * 0.5 * var(--scale))
|
|
||||||
}
|
|
||||||
|
|
||||||
.chunk {
|
|
||||||
background-color: #e2b188;
|
|
||||||
box-shadow: 0.01em 0.01em 0.1em 0 #e2b188;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chunk-P {
|
|
||||||
grid-area: P;
|
|
||||||
border-top-left-radius: calc(var(--logoChunkSize) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#chunk-L {
|
|
||||||
grid-area: L;
|
|
||||||
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#chunk-E {
|
|
||||||
grid-area: E;
|
|
||||||
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#status {
|
|
||||||
margin-top: 1em;
|
|
||||||
line-height: 2;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#statusError {
|
|
||||||
display: none;
|
|
||||||
margin-top: 1em;
|
|
||||||
font-size: calc(1vw + 1vh + 1vmin);
|
|
||||||
line-height: 2;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#statusStack {
|
|
||||||
display: none;
|
|
||||||
margin-top: 1em;
|
|
||||||
font-size: calc((1vw + 1vh + 1vmin) / 2.5);
|
|
||||||
width: calc(100vw - 5em);
|
|
||||||
padding: 1em;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow-x: hidden;
|
|
||||||
text-align: left;
|
|
||||||
line-height: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion) {
|
|
||||||
#throbber {
|
|
||||||
animation: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style id="pleroma-eager-styles" type="text/css"></style>
|
|
||||||
<style id="pleroma-lazy-styles" type="text/css"></style>
|
|
||||||
<!--server-generated-meta-->
|
<!--server-generated-meta-->
|
||||||
</head>
|
</head>
|
||||||
<body style="margin: 0; padding: 0">
|
<body>
|
||||||
<noscript>To use Pleroma, please enable JavaScript.</noscript>
|
<noscript>To use Pleroma, please enable JavaScript.</noscript>
|
||||||
<div id="splash">
|
<div id="splash">
|
||||||
<!-- we are hiding entire graphic so no point showing credit -->
|
<!-- we are hiding entire graphic so no point showing credit -->
|
||||||
|
|
|
||||||
14
package.json
14
package.json
|
|
@ -23,7 +23,7 @@
|
||||||
"@fortawesome/free-regular-svg-icons": "6.7.2",
|
"@fortawesome/free-regular-svg-icons": "6.7.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "6.7.2",
|
"@fortawesome/free-solid-svg-icons": "6.7.2",
|
||||||
"@fortawesome/vue-fontawesome": "3.0.8",
|
"@fortawesome/vue-fontawesome": "3.0.8",
|
||||||
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
|
"@kazvmoe-infra/pinch-zoom-element": "1.3.0",
|
||||||
"@kazvmoe-infra/unicode-emoji-json": "0.4.0",
|
"@kazvmoe-infra/unicode-emoji-json": "0.4.0",
|
||||||
"@ruffle-rs/ruffle": "0.1.0-nightly.2025.1.13",
|
"@ruffle-rs/ruffle": "0.1.0-nightly.2025.1.13",
|
||||||
"@vuelidate/core": "2.0.3",
|
"@vuelidate/core": "2.0.3",
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
"url": "0.11.4",
|
"url": "0.11.4",
|
||||||
"utf8": "3.0.0",
|
"utf8": "3.0.0",
|
||||||
"uuid": "11.1.0",
|
"uuid": "11.1.0",
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.17",
|
||||||
"vue-i18n": "11",
|
"vue-i18n": "11",
|
||||||
"vue-router": "4.5.1",
|
"vue-router": "4.5.1",
|
||||||
"vue-virtual-scroller": "^2.0.0-beta.7",
|
"vue-virtual-scroller": "^2.0.0-beta.7",
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
"@vitest/ui": "^3.0.7",
|
"@vitest/ui": "^3.0.7",
|
||||||
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
|
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
|
||||||
"@vue/babel-plugin-jsx": "1.4.0",
|
"@vue/babel-plugin-jsx": "1.4.0",
|
||||||
"@vue/compiler-sfc": "3.5.13",
|
"@vue/compiler-sfc": "3.5.17",
|
||||||
"@vue/test-utils": "2.4.6",
|
"@vue/test-utils": "2.4.6",
|
||||||
"autoprefixer": "10.4.21",
|
"autoprefixer": "10.4.21",
|
||||||
"babel-plugin-lodash": "3.3.4",
|
"babel-plugin-lodash": "3.3.4",
|
||||||
|
|
@ -90,17 +90,17 @@
|
||||||
"http-proxy-middleware": "3.0.5",
|
"http-proxy-middleware": "3.0.5",
|
||||||
"iso-639-1": "3.1.5",
|
"iso-639-1": "3.1.5",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"msw": "2.7.6",
|
"msw": "2.10.2",
|
||||||
"nightwatch": "3.12.1",
|
"nightwatch": "3.12.1",
|
||||||
"playwright": "1.52.0",
|
"playwright": "1.52.0",
|
||||||
"postcss": "8.5.3",
|
"postcss": "8.5.3",
|
||||||
"postcss-html": "^1.5.0",
|
"postcss-html": "^1.5.0",
|
||||||
"postcss-scss": "^4.0.6",
|
"postcss-scss": "^4.0.6",
|
||||||
"sass": "1.87.0",
|
"sass": "1.89.2",
|
||||||
"selenium-server": "3.141.59",
|
"selenium-server": "3.141.59",
|
||||||
"semver": "7.7.1",
|
"semver": "7.7.2",
|
||||||
"serve-static": "2.2.0",
|
"serve-static": "2.2.0",
|
||||||
"shelljs": "0.9.2",
|
"shelljs": "0.10.0",
|
||||||
"sinon": "20.0.0",
|
"sinon": "20.0.0",
|
||||||
"sinon-chai": "4.0.0",
|
"sinon-chai": "4.0.0",
|
||||||
"stylelint": "16.19.1",
|
"stylelint": "16.19.1",
|
||||||
|
|
|
||||||
126
public/static/splash.css
Normal file
126
public/static/splash.css
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#splash {
|
||||||
|
--scale: 1;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
justify-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #0f161e;
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #b9b9ba;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9999;
|
||||||
|
font-size: calc(1vw + 1vh + 1vmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#splash-credit {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 14px;
|
||||||
|
bottom: 16px;
|
||||||
|
right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#splash-container {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mascot-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
perspective: 60em;
|
||||||
|
perspective-origin: 0 -15em;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mascot {
|
||||||
|
width: calc(10em * var(--scale));
|
||||||
|
height: calc(10em * var(--scale));
|
||||||
|
object-fit: contain;
|
||||||
|
object-position: bottom;
|
||||||
|
transform: translateZ(-2em);
|
||||||
|
}
|
||||||
|
|
||||||
|
#throbber {
|
||||||
|
display: grid;
|
||||||
|
width: calc(5em * 0.5 * var(--scale));
|
||||||
|
height: calc(8em * 0.5 * var(--scale));
|
||||||
|
margin-left: 4.1em;
|
||||||
|
z-index: 2;
|
||||||
|
grid-template-rows: repeat(8, 1fr);
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
grid-template-areas: "P P . L L"
|
||||||
|
"P P . L L"
|
||||||
|
"P P . L L"
|
||||||
|
"P P . L L"
|
||||||
|
"P P . . ."
|
||||||
|
"P P . . ."
|
||||||
|
"P P . E E"
|
||||||
|
"P P . E E";
|
||||||
|
|
||||||
|
--logoChunkSize: calc(2em * 0.5 * var(--scale))
|
||||||
|
}
|
||||||
|
|
||||||
|
.chunk {
|
||||||
|
background-color: #e2b188;
|
||||||
|
box-shadow: 0.01em 0.01em 0.1em 0 #e2b188;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chunk-P {
|
||||||
|
grid-area: P;
|
||||||
|
border-top-left-radius: calc(var(--logoChunkSize) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#chunk-L {
|
||||||
|
grid-area: L;
|
||||||
|
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#chunk-E {
|
||||||
|
grid-area: E;
|
||||||
|
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#status {
|
||||||
|
margin-top: 1em;
|
||||||
|
line-height: 2;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#statusError {
|
||||||
|
display: none;
|
||||||
|
margin-top: 1em;
|
||||||
|
font-size: calc(1vw + 1vh + 1vmin);
|
||||||
|
line-height: 2;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#statusStack {
|
||||||
|
display: none;
|
||||||
|
margin-top: 1em;
|
||||||
|
font-size: calc((1vw + 1vh + 1vmin) / 2.5);
|
||||||
|
width: calc(100vw - 5em);
|
||||||
|
padding: 1em;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow-x: hidden;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion) {
|
||||||
|
#throbber {
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ import EditStatusModal from './components/edit_status_modal/edit_status_modal.vu
|
||||||
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
||||||
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
|
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
|
||||||
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
||||||
|
import { getOrCreateServiceWorker } from './services/sw/sw'
|
||||||
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
|
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { defineAsyncComponent } from 'vue'
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
|
@ -77,6 +78,7 @@ export default {
|
||||||
this.setThemeBodyClass()
|
this.setThemeBodyClass()
|
||||||
this.removeSplash()
|
this.removeSplash()
|
||||||
}
|
}
|
||||||
|
getOrCreateServiceWorker()
|
||||||
},
|
},
|
||||||
unmounted () {
|
unmounted () {
|
||||||
window.removeEventListener('resize', this.updateMobileState)
|
window.removeEventListener('resize', this.updateMobileState)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
/* stylelint-disable no-descending-specificity */
|
/* stylelint-disable no-descending-specificity */
|
||||||
@use "panel";
|
@use "panel";
|
||||||
|
|
||||||
|
@import '@fortawesome/fontawesome-svg-core/styles.css';
|
||||||
|
@import '@kazvmoe-infra/pinch-zoom-element/dist/pinch-zoom.css';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--status-margin: 0.75em;
|
--status-margin: 0.75em;
|
||||||
--post-line-height: 1.4;
|
--post-line-height: 1.4;
|
||||||
|
|
@ -30,6 +33,7 @@ body {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-family: var(--font);
|
font-family: var(--font);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import VueVirtualScroller from 'vue-virtual-scroller'
|
||||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||||
|
|
||||||
import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
|
||||||
|
import { config } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
config.autoAddCss = false
|
||||||
|
|
||||||
import App from '../App.vue'
|
import App from '../App.vue'
|
||||||
import routes from './routes'
|
import routes from './routes'
|
||||||
|
|
@ -21,6 +23,7 @@ import { useOAuthStore } from 'src/stores/oauth'
|
||||||
import { useI18nStore } from 'src/stores/i18n'
|
import { useI18nStore } from 'src/stores/i18n'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { useAnnouncementsStore } from 'src/stores/announcements'
|
import { useAnnouncementsStore } from 'src/stores/announcements'
|
||||||
|
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
||||||
|
|
||||||
let staticInitialResults = null
|
let staticInitialResults = null
|
||||||
|
|
||||||
|
|
@ -63,10 +66,11 @@ const getInstanceConfig = async ({ store }) => {
|
||||||
const textlimit = data.max_toot_chars
|
const textlimit = data.max_toot_chars
|
||||||
const vapidPublicKey = data.pleroma.vapid_public_key
|
const vapidPublicKey = data.pleroma.vapid_public_key
|
||||||
|
|
||||||
|
store.dispatch('setInstanceOption', { name: 'pleromaExtensionsAvailable', value: data.pleroma })
|
||||||
store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit })
|
store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit })
|
||||||
store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.approval_required })
|
store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.approval_required })
|
||||||
store.dispatch('setInstanceOption', { name: 'birthdayRequired', value: !!data.pleroma.metadata.birthday_required })
|
store.dispatch('setInstanceOption', { name: 'birthdayRequired', value: !!data.pleroma?.metadata.birthday_required })
|
||||||
store.dispatch('setInstanceOption', { name: 'birthdayMinAge', value: data.pleroma.metadata.birthday_min_age || 0 })
|
store.dispatch('setInstanceOption', { name: 'birthdayMinAge', value: data.pleroma?.metadata.birthday_min_age || 0 })
|
||||||
|
|
||||||
if (vapidPublicKey) {
|
if (vapidPublicKey) {
|
||||||
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })
|
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })
|
||||||
|
|
@ -78,6 +82,8 @@ const getInstanceConfig = async ({ store }) => {
|
||||||
console.error('Could not load instance config, potentially fatal')
|
console.error('Could not load instance config, potentially fatal')
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
// We should check for scrobbles support here but it requires userId
|
||||||
|
// so instead we check for it where it's fetched (statuses.js)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBackendProvidedConfig = async () => {
|
const getBackendProvidedConfig = async () => {
|
||||||
|
|
@ -153,7 +159,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
||||||
: config.logoMargin
|
: config.logoMargin
|
||||||
})
|
})
|
||||||
copyInstanceOption('logoLeft')
|
copyInstanceOption('logoLeft')
|
||||||
store.commit('authFlow/setInitialStrategy', config.loginMethod)
|
useAuthFlowStore().setInitialStrategy(config.loginMethod)
|
||||||
|
|
||||||
copyInstanceOption('redirectRootNoLogin')
|
copyInstanceOption('redirectRootNoLogin')
|
||||||
copyInstanceOption('redirectRootLogin')
|
copyInstanceOption('redirectRootLogin')
|
||||||
|
|
@ -242,7 +248,8 @@ const resolveStaffAccounts = ({ store, accounts }) => {
|
||||||
|
|
||||||
const getNodeInfo = async ({ store }) => {
|
const getNodeInfo = async ({ store }) => {
|
||||||
try {
|
try {
|
||||||
const res = await preloadFetch('/nodeinfo/2.1.json')
|
let res = await preloadFetch('/nodeinfo/2.1.json')
|
||||||
|
if (!res.ok) res = await preloadFetch('/nodeinfo/2.0.json')
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
const metadata = data.metadata
|
const metadata = data.metadata
|
||||||
|
|
@ -254,7 +261,12 @@ const getNodeInfo = async ({ store }) => {
|
||||||
store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
|
store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
|
||||||
store.dispatch('setInstanceOption', { name: 'shoutAvailable', value: features.includes('chat') })
|
store.dispatch('setInstanceOption', { name: 'shoutAvailable', value: features.includes('chat') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') })
|
store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pleromaCustomEmojiReactionsAvailable', value: features.includes('pleroma_custom_emoji_reactions') })
|
store.dispatch('setInstanceOption', {
|
||||||
|
name: 'pleromaCustomEmojiReactionsAvailable',
|
||||||
|
value:
|
||||||
|
features.includes('pleroma_custom_emoji_reactions') ||
|
||||||
|
features.includes('custom_emoji_reactions')
|
||||||
|
})
|
||||||
store.dispatch('setInstanceOption', { name: 'pleromaBookmarkFoldersAvailable', value: features.includes('pleroma:bookmark_folders') })
|
store.dispatch('setInstanceOption', { name: 'pleromaBookmarkFoldersAvailable', value: features.includes('pleroma:bookmark_folders') })
|
||||||
store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
|
store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
||||||
|
|
@ -264,6 +276,7 @@ const getNodeInfo = async ({ store }) => {
|
||||||
store.dispatch('setInstanceOption', { name: 'quotingAvailable', value: features.includes('quote_posting') })
|
store.dispatch('setInstanceOption', { name: 'quotingAvailable', value: features.includes('quote_posting') })
|
||||||
store.dispatch('setInstanceOption', { name: 'groupActorAvailable', value: features.includes('pleroma:group_actors') })
|
store.dispatch('setInstanceOption', { name: 'groupActorAvailable', value: features.includes('pleroma:group_actors') })
|
||||||
store.dispatch('setInstanceOption', { name: 'blockExpiration', value: features.includes('pleroma:block_expiration') })
|
store.dispatch('setInstanceOption', { name: 'blockExpiration', value: features.includes('pleroma:block_expiration') })
|
||||||
|
store.dispatch('setInstanceOption', { name: 'localBubbleInstances', value: metadata.localBubbleInstances ?? [] })
|
||||||
|
|
||||||
const uploadLimits = metadata.uploadLimits
|
const uploadLimits = metadata.uploadLimits
|
||||||
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
|
||||||
|
|
@ -282,7 +295,6 @@ const getNodeInfo = async ({ store }) => {
|
||||||
const software = data.software
|
const software = data.software
|
||||||
store.dispatch('setInstanceOption', { name: 'backendVersion', value: software.version })
|
store.dispatch('setInstanceOption', { name: 'backendVersion', value: software.version })
|
||||||
store.dispatch('setInstanceOption', { name: 'backendRepository', value: software.repository })
|
store.dispatch('setInstanceOption', { name: 'backendRepository', value: software.repository })
|
||||||
store.dispatch('setInstanceOption', { name: 'pleromaBackend', value: software.name === 'pleroma' })
|
|
||||||
|
|
||||||
const priv = metadata.private
|
const priv = metadata.private
|
||||||
store.dispatch('setInstanceOption', { name: 'private', value: priv })
|
store.dispatch('setInstanceOption', { name: 'private', value: priv })
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import PublicTimeline from 'components/public_timeline/public_timeline.vue'
|
import PublicTimeline from 'components/public_timeline/public_timeline.vue'
|
||||||
|
import BubbleTimeline from 'components/bubble_timeline/bubble_timeline.vue'
|
||||||
import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue'
|
import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue'
|
||||||
import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue'
|
import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue'
|
||||||
import TagTimeline from 'components/tag_timeline/tag_timeline.vue'
|
import TagTimeline from 'components/tag_timeline/tag_timeline.vue'
|
||||||
|
|
@ -54,6 +55,7 @@ export default (store) => {
|
||||||
{ name: 'friends', path: '/main/friends', component: FriendsTimeline, beforeEnter: validateAuthenticatedRoute },
|
{ name: 'friends', path: '/main/friends', component: FriendsTimeline, beforeEnter: validateAuthenticatedRoute },
|
||||||
{ name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
|
{ name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
|
||||||
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
|
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
|
||||||
|
{ name: 'bubble', path: '/bubble', component: BubbleTimeline },
|
||||||
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
|
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
|
||||||
{ name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline },
|
{ name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline },
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ import { h, resolveComponent } from 'vue'
|
||||||
import LoginForm from '../login_form/login_form.vue'
|
import LoginForm from '../login_form/login_form.vue'
|
||||||
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
|
||||||
import MFATOTPForm from '../mfa_form/totp_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 = {
|
const AuthForm = {
|
||||||
name: 'AuthForm',
|
name: 'AuthForm',
|
||||||
|
|
@ -15,7 +16,7 @@ const AuthForm = {
|
||||||
if (this.requiredRecovery) { return 'MFARecoveryForm' }
|
if (this.requiredRecovery) { return 'MFARecoveryForm' }
|
||||||
return 'LoginForm'
|
return 'LoginForm'
|
||||||
},
|
},
|
||||||
...mapGetters('authFlow', ['requiredTOTP', 'requiredRecovery'])
|
...mapState(useAuthFlowStore, ['requiredTOTP', 'requiredRecovery'])
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
MFARecoveryForm,
|
MFARecoveryForm,
|
||||||
|
|
|
||||||
18
src/components/bubble_timeline/bubble_timeline.js
Normal file
18
src/components/bubble_timeline/bubble_timeline.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
import Timeline from '../timeline/timeline.vue'
|
||||||
|
const BubbleTimeline = {
|
||||||
|
components: {
|
||||||
|
Timeline
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
timeline () { return this.$store.state.statuses.timelines.bubble }
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.$store.dispatch('startFetchingTimeline', { timeline: 'bubble' })
|
||||||
|
},
|
||||||
|
unmounted () {
|
||||||
|
this.$store.dispatch('stopFetchingTimeline', 'bubble')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BubbleTimeline
|
||||||
9
src/components/bubble_timeline/bubble_timeline.vue
Normal file
9
src/components/bubble_timeline/bubble_timeline.vue
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<Timeline
|
||||||
|
:title="$t('nav.bubble')"
|
||||||
|
:timeline="timeline"
|
||||||
|
:timeline-name="'bubble'"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script src="./bubble_timeline.js"></script>
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
class="textColor unstyled"
|
class="textColor unstyled"
|
||||||
:class="{ disabled: !present || disabled }"
|
:class="{ disabled: !present || disabled }"
|
||||||
type="text"
|
type="text"
|
||||||
:value="modelValue || fallback"
|
:value="modelValue ?? fallback"
|
||||||
:disabled="!present || disabled"
|
:disabled="!present || disabled"
|
||||||
@input="updateValue($event.target.value)"
|
@input="updateValue($event.target.value)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
82
src/components/component_preview/component_preview.js
Normal file
82
src/components/component_preview/component_preview.js
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
||||||
|
import ColorInput from 'src/components/color_input/color_input.vue'
|
||||||
|
|
||||||
|
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
|
||||||
|
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Checkbox,
|
||||||
|
ColorInput
|
||||||
|
},
|
||||||
|
props: [
|
||||||
|
'shadow',
|
||||||
|
'shadowControl',
|
||||||
|
'previewClass',
|
||||||
|
'previewStyle',
|
||||||
|
'previewCss',
|
||||||
|
'disabled',
|
||||||
|
'invalid',
|
||||||
|
'noColorControl'
|
||||||
|
],
|
||||||
|
emits: ['update:shadow'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
colorOverride: undefined,
|
||||||
|
lightGrid: false,
|
||||||
|
zoom: 100,
|
||||||
|
randomSeed: genRandomSeed()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hideControls () {
|
||||||
|
return typeof this.shadow === 'string'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
previewCss () {
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
previewStyle () {
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
zoom () {
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateProperty (axis, value) {
|
||||||
|
this.$emit('update:shadow', { axis, value: Number(value) })
|
||||||
|
},
|
||||||
|
update () {
|
||||||
|
const sheet = createStyleSheet('style-component-preview', 90)
|
||||||
|
|
||||||
|
sheet.clear()
|
||||||
|
|
||||||
|
const result = [this.previewCss]
|
||||||
|
if (this.colorOverride) result.push(`--background: ${this.colorOverride}`)
|
||||||
|
|
||||||
|
const styleRule = [
|
||||||
|
'#component-preview-', this.randomSeed, ' {\n',
|
||||||
|
'.preview-block {\n',
|
||||||
|
`zoom: ${this.zoom / 100};`,
|
||||||
|
this.previewStyle,
|
||||||
|
'\n}',
|
||||||
|
'\n}'
|
||||||
|
].join('')
|
||||||
|
|
||||||
|
sheet.addRule(styleRule)
|
||||||
|
sheet.addRule([
|
||||||
|
'#component-preview-', this.randomSeed, ' {\n',
|
||||||
|
...result,
|
||||||
|
'\n}'
|
||||||
|
].join(''))
|
||||||
|
|
||||||
|
sheet.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
151
src/components/component_preview/component_preview.scss
Normal file
151
src/components/component_preview/component_preview.scss
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
.ComponentPreview {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1em 1fr 1fr 1em;
|
||||||
|
grid-template-rows: 2em 1fr 1fr 1fr 1em 2em max-content;
|
||||||
|
grid-template-areas:
|
||||||
|
"header header header header "
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"x-slide x-slide x-slide . "
|
||||||
|
"x-num x-num y-num y-num "
|
||||||
|
"assists assists assists assists";
|
||||||
|
grid-gap: 0.5em;
|
||||||
|
|
||||||
|
&:not(.-shadow-controls) {
|
||||||
|
grid-template-areas:
|
||||||
|
"header header header header "
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"preview preview preview y-slide"
|
||||||
|
"assists assists assists assists";
|
||||||
|
grid-template-rows: 2em 1fr 1fr 1fr max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
grid-area: header;
|
||||||
|
place-self: baseline center;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invalid-container {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: grid;
|
||||||
|
place-items: center center;
|
||||||
|
background-color: rgb(100 0 0 / 50%);
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.assists {
|
||||||
|
grid-area: assists;
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: row;
|
||||||
|
grid-auto-rows: 2em;
|
||||||
|
grid-gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-light-grid {
|
||||||
|
justify-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-number {
|
||||||
|
min-width: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-shift-number {
|
||||||
|
grid-area: x-num;
|
||||||
|
justify-self: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.y-shift-number {
|
||||||
|
grid-area: y-num;
|
||||||
|
justify-self: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-shift-number,
|
||||||
|
.y-shift-number {
|
||||||
|
input {
|
||||||
|
max-width: 4em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-shift-slider {
|
||||||
|
grid-area: x-slide;
|
||||||
|
height: auto;
|
||||||
|
align-self: start;
|
||||||
|
min-width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.y-shift-slider {
|
||||||
|
grid-area: y-slide;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
justify-self: left;
|
||||||
|
min-height: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-shift-slider,
|
||||||
|
.y-shift-slider {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-window {
|
||||||
|
--__grid-color1: rgb(102 102 102);
|
||||||
|
--__grid-color2: rgb(153 153 153);
|
||||||
|
--__grid-color1-disabled: rgb(102 102 102 / 20%);
|
||||||
|
--__grid-color2-disabled: rgb(153 153 153 / 20%);
|
||||||
|
|
||||||
|
&.-light-grid {
|
||||||
|
--__grid-color1: rgb(205 205 205);
|
||||||
|
--__grid-color2: rgb(255 255 255);
|
||||||
|
--__grid-color1-disabled: rgb(205 205 205 / 20%);
|
||||||
|
--__grid-color2-disabled: rgb(255 255 255 / 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
grid-area: preview;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 10em;
|
||||||
|
min-height: 10em;
|
||||||
|
background-color: var(--__grid-color2);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, var(--__grid-color1) 25%, transparent 25%),
|
||||||
|
linear-gradient(-45deg, var(--__grid-color1) 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, var(--__grid-color1) 75%),
|
||||||
|
linear-gradient(-45deg, transparent 75%, var(--__grid-color1) 75%);
|
||||||
|
background-size: 20px 20px;
|
||||||
|
background-position: 0 0, 0 10px, 10px -10px, -10px 0;
|
||||||
|
border-radius: var(--roundness);
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
background-color: var(--__grid-color2-disabled);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, var(--__grid-color1-disabled) 25%, transparent 25%),
|
||||||
|
linear-gradient(-45deg, var(--__grid-color1-disabled) 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, var(--__grid-color1-disabled) 75%),
|
||||||
|
linear-gradient(-45deg, transparent 75%, var(--__grid-color1-disabled) 75%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-block {
|
||||||
|
background: var(--background, var(--bg));
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 33%;
|
||||||
|
min-height: 33%;
|
||||||
|
max-width: 80%;
|
||||||
|
max-height: 80%;
|
||||||
|
border-width: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: var(--border);
|
||||||
|
border-radius: var(--roundness);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
:id="'component-preview-' + randomSeed"
|
||||||
class="ComponentPreview"
|
class="ComponentPreview"
|
||||||
:class="{ '-shadow-controls': shadowControl }"
|
:class="{ '-shadow-controls': shadowControl }"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="previewCss"
|
|
||||||
/>
|
|
||||||
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<label
|
<label
|
||||||
v-show="shadowControl"
|
v-show="shadowControl"
|
||||||
role="heading"
|
role="heading"
|
||||||
|
|
@ -74,7 +69,6 @@
|
||||||
<div
|
<div
|
||||||
class="preview-block"
|
class="preview-block"
|
||||||
:class="previewClass"
|
:class="previewClass"
|
||||||
:style="style"
|
|
||||||
>
|
>
|
||||||
{{ $t('settings.style.themes3.editor.test_string') }}
|
{{ $t('settings.style.themes3.editor.test_string') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -116,203 +110,5 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script src="./component_preview.js" />
|
||||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
<style src="./component_preview.scss" lang="scss" />
|
||||||
import ColorInput from 'src/components/color_input/color_input.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
Checkbox,
|
|
||||||
ColorInput
|
|
||||||
},
|
|
||||||
props: [
|
|
||||||
'shadow',
|
|
||||||
'shadowControl',
|
|
||||||
'previewClass',
|
|
||||||
'previewStyle',
|
|
||||||
'previewCss',
|
|
||||||
'disabled',
|
|
||||||
'invalid',
|
|
||||||
'noColorControl'
|
|
||||||
],
|
|
||||||
emits: ['update:shadow'],
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
colorOverride: undefined,
|
|
||||||
lightGrid: false,
|
|
||||||
zoom: 100
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
style () {
|
|
||||||
const result = [
|
|
||||||
this.previewStyle,
|
|
||||||
`zoom: ${this.zoom / 100}`
|
|
||||||
]
|
|
||||||
if (this.colorOverride) result.push(`--background: ${this.colorOverride}`)
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
hideControls () {
|
|
||||||
return typeof this.shadow === 'string'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
updateProperty (axis, value) {
|
|
||||||
this.$emit('update:shadow', { axis, value: Number(value) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss">
|
|
||||||
.ComponentPreview {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1em 1fr 1fr 1em;
|
|
||||||
grid-template-rows: 2em 1fr 1fr 1fr 1em 2em max-content;
|
|
||||||
grid-template-areas:
|
|
||||||
"header header header header "
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"x-slide x-slide x-slide . "
|
|
||||||
"x-num x-num y-num y-num "
|
|
||||||
"assists assists assists assists";
|
|
||||||
grid-gap: 0.5em;
|
|
||||||
|
|
||||||
&:not(.-shadow-controls) {
|
|
||||||
grid-template-areas:
|
|
||||||
"header header header header "
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"preview preview preview y-slide"
|
|
||||||
"assists assists assists assists";
|
|
||||||
grid-template-rows: 2em 1fr 1fr 1fr max-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
grid-area: header;
|
|
||||||
place-self: baseline center;
|
|
||||||
line-height: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.invalid-container {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: grid;
|
|
||||||
place-items: center center;
|
|
||||||
background-color: rgb(100 0 0 / 50%);
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.assists {
|
|
||||||
grid-area: assists;
|
|
||||||
display: grid;
|
|
||||||
grid-auto-flow: row;
|
|
||||||
grid-auto-rows: 2em;
|
|
||||||
grid-gap: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-light-grid {
|
|
||||||
justify-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-number {
|
|
||||||
min-width: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.x-shift-number {
|
|
||||||
grid-area: x-num;
|
|
||||||
justify-self: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.y-shift-number {
|
|
||||||
grid-area: y-num;
|
|
||||||
justify-self: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.x-shift-number,
|
|
||||||
.y-shift-number {
|
|
||||||
input {
|
|
||||||
max-width: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.x-shift-slider {
|
|
||||||
grid-area: x-slide;
|
|
||||||
height: auto;
|
|
||||||
align-self: start;
|
|
||||||
min-width: 10em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.y-shift-slider {
|
|
||||||
grid-area: y-slide;
|
|
||||||
writing-mode: vertical-lr;
|
|
||||||
justify-self: left;
|
|
||||||
min-height: 10em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.x-shift-slider,
|
|
||||||
.y-shift-slider {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-window {
|
|
||||||
--__grid-color1: rgb(102 102 102);
|
|
||||||
--__grid-color2: rgb(153 153 153);
|
|
||||||
--__grid-color1-disabled: rgb(102 102 102 / 20%);
|
|
||||||
--__grid-color2-disabled: rgb(153 153 153 / 20%);
|
|
||||||
|
|
||||||
&.-light-grid {
|
|
||||||
--__grid-color1: rgb(205 205 205);
|
|
||||||
--__grid-color2: rgb(255 255 255);
|
|
||||||
--__grid-color1-disabled: rgb(205 205 205 / 20%);
|
|
||||||
--__grid-color2-disabled: rgb(255 255 255 / 20%);
|
|
||||||
}
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
grid-area: preview;
|
|
||||||
aspect-ratio: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-width: 10em;
|
|
||||||
min-height: 10em;
|
|
||||||
background-color: var(--__grid-color2);
|
|
||||||
background-image:
|
|
||||||
linear-gradient(45deg, var(--__grid-color1) 25%, transparent 25%),
|
|
||||||
linear-gradient(-45deg, var(--__grid-color1) 25%, transparent 25%),
|
|
||||||
linear-gradient(45deg, transparent 75%, var(--__grid-color1) 75%),
|
|
||||||
linear-gradient(-45deg, transparent 75%, var(--__grid-color1) 75%);
|
|
||||||
background-size: 20px 20px;
|
|
||||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0;
|
|
||||||
border-radius: var(--roundness);
|
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
background-color: var(--__grid-color2-disabled);
|
|
||||||
background-image:
|
|
||||||
linear-gradient(45deg, var(--__grid-color1-disabled) 25%, transparent 25%),
|
|
||||||
linear-gradient(-45deg, var(--__grid-color1-disabled) 25%, transparent 25%),
|
|
||||||
linear-gradient(45deg, transparent 75%, var(--__grid-color1-disabled) 75%),
|
|
||||||
linear-gradient(-45deg, transparent 75%, var(--__grid-color1-disabled) 75%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-block {
|
|
||||||
background: var(--background, var(--bg));
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 33%;
|
|
||||||
min-height: 33%;
|
|
||||||
max-width: 80%;
|
|
||||||
max-height: 80%;
|
|
||||||
border-width: 0;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: var(--border);
|
|
||||||
border-radius: var(--roundness);
|
|
||||||
box-shadow: var(--shadow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import oauthApi from '../../services/new_api/oauth.js'
|
import oauthApi from '../../services/new_api/oauth.js'
|
||||||
import { useOAuthStore } from 'src/stores/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 { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -25,13 +26,10 @@ const LoginForm = {
|
||||||
instance: state => state.instance,
|
instance: state => state.instance,
|
||||||
loggingIn: state => state.users.loggingIn,
|
loggingIn: state => state.users.loggingIn,
|
||||||
}),
|
}),
|
||||||
...mapGetters(
|
...mapPiniaState(useAuthFlowStore, ['requiredPassword', 'requiredToken', 'requiredMFA'])
|
||||||
'authFlow', ['requiredPassword', 'requiredToken', 'requiredMFA']
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireMFA']),
|
...mapActions(useAuthFlowStore, ['requireMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
submit () {
|
submit () {
|
||||||
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
this.isTokenAuth ? this.submitToken() : this.submitPassword()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import mfaApi from '../../services/new_api/mfa.js'
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import { useOAuthStore } from 'src/stores/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 { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -17,8 +18,8 @@ export default {
|
||||||
error: false
|
error: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapPiniaState(useAuthFlowStore, {
|
||||||
authSettings: 'authFlow/settings'
|
authSettings: store => store.settings
|
||||||
}),
|
}),
|
||||||
...mapStores(useOAuthStore),
|
...mapStores(useOAuthStore),
|
||||||
...mapState({
|
...mapState({
|
||||||
|
|
@ -26,8 +27,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireTOTP', 'abortMFA']),
|
...mapActions(useAuthFlowStore, ['requireTOTP', 'abortMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
clearError () { this.error = false },
|
clearError () { this.error = false },
|
||||||
|
|
||||||
focusOnCodeInput () {
|
focusOnCodeInput () {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import mfaApi from '../../services/new_api/mfa.js'
|
import mfaApi from '../../services/new_api/mfa.js'
|
||||||
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { mapStores } from 'pinia'
|
import { mapStores, mapActions, mapState as mapPiniaState } from 'pinia'
|
||||||
import { useOAuthStore } from 'src/stores/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 { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faTimes
|
faTimes
|
||||||
|
|
@ -17,8 +18,8 @@ export default {
|
||||||
error: false
|
error: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapPiniaState(useAuthFlowStore, {
|
||||||
authSettings: 'authFlow/settings'
|
authSettings: store => store.settings
|
||||||
}),
|
}),
|
||||||
...mapStores(useOAuthStore),
|
...mapStores(useOAuthStore),
|
||||||
...mapState({
|
...mapState({
|
||||||
|
|
@ -26,8 +27,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('authFlow', ['requireRecovery', 'abortMFA']),
|
...mapActions(useAuthFlowStore, ['requireRecovery', 'abortMFA', 'login']),
|
||||||
...mapActions({ login: 'authFlow/login' }),
|
|
||||||
clearError () { this.error = false },
|
clearError () { this.error = false },
|
||||||
|
|
||||||
focusOnCodeInput () {
|
focusOnCodeInput () {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faUsers,
|
faUsers,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faCity,
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
|
|
@ -31,6 +32,7 @@ import {
|
||||||
library.add(
|
library.add(
|
||||||
faUsers,
|
faUsers,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faCity,
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
|
|
@ -108,12 +110,15 @@ const NavPanel = {
|
||||||
privateMode: state => state.instance.private,
|
privateMode: state => state.instance.private,
|
||||||
federating: state => state.instance.federating,
|
federating: state => state.instance.federating,
|
||||||
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
|
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
|
||||||
bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable
|
bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable,
|
||||||
|
bubbleTimeline: state => state.instance.localBubbleInstances.length > 0
|
||||||
}),
|
}),
|
||||||
timelinesItems () {
|
timelinesItems () {
|
||||||
return filterNavigation(
|
return filterNavigation(
|
||||||
Object
|
Object
|
||||||
.entries({ ...TIMELINES })
|
.entries({ ...TIMELINES })
|
||||||
|
// do not show in timeliens list since it's in a better place now
|
||||||
|
.filter(([key]) => key !== 'bookmarks')
|
||||||
.map(([k, v]) => ({ ...v, name: k })),
|
.map(([k, v]) => ({ ...v, name: k })),
|
||||||
{
|
{
|
||||||
hasChats: this.pleromaChatMessagesAvailable,
|
hasChats: this.pleromaChatMessagesAvailable,
|
||||||
|
|
@ -121,6 +126,7 @@ const NavPanel = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
|
supportsBubbleTimeline: this.bubbleTimeline,
|
||||||
supportsBookmarkFolders: this.bookmarkFolders
|
supportsBookmarkFolders: this.bookmarkFolders
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -136,6 +142,7 @@ const NavPanel = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
|
supportsBubbleTimeline: this.bubbleTimeline,
|
||||||
supportsBookmarkFolders: this.bookmarkFolders
|
supportsBookmarkFolders: this.bookmarkFolders
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,12 @@
|
||||||
export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser, supportsBookmarkFolders }) => {
|
export const filterNavigation = (list = [], {
|
||||||
|
hasChats,
|
||||||
|
hasAnnouncements,
|
||||||
|
isFederating,
|
||||||
|
isPrivate,
|
||||||
|
currentUser,
|
||||||
|
supportsBookmarkFolders,
|
||||||
|
supportsBubbleTimeline
|
||||||
|
}) => {
|
||||||
return list.filter(({ criteria, anon, anonRoute }) => {
|
return list.filter(({ criteria, anon, anonRoute }) => {
|
||||||
const set = new Set(criteria || [])
|
const set = new Set(criteria || [])
|
||||||
if (!isFederating && set.has('federating')) return false
|
if (!isFederating && set.has('federating')) return false
|
||||||
|
|
@ -7,6 +15,8 @@ export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFede
|
||||||
if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false
|
if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false
|
||||||
if (!hasChats && set.has('chats')) return false
|
if (!hasChats && set.has('chats')) return false
|
||||||
if (!hasAnnouncements && set.has('announcements')) return false
|
if (!hasAnnouncements && set.has('announcements')) return false
|
||||||
|
if (!supportsBubbleTimeline && set.has('supportsBubbleTimeline')) return false
|
||||||
|
if (!supportsBookmarkFolders && set.has('supportsBookmarkFolders')) return false
|
||||||
if (supportsBookmarkFolders && set.has('!supportsBookmarkFolders')) return false
|
if (supportsBookmarkFolders && set.has('!supportsBookmarkFolders')) return false
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
@ -19,11 +29,11 @@ export const getListEntries = store => store.allLists.map(list => ({
|
||||||
iconLetter: list.title[0]
|
iconLetter: list.title[0]
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export const getBookmarkFolderEntries = store => store.allFolders.map(folder => ({
|
export const getBookmarkFolderEntries = store => store.allFolders ? store.allFolders.map(folder => ({
|
||||||
name: 'bookmark-folder-' + folder.id,
|
name: 'bookmark-folder-' + folder.id,
|
||||||
routeObject: { name: 'bookmark-folder', params: { id: folder.id } },
|
routeObject: { name: 'bookmark-folder', params: { id: folder.id } },
|
||||||
labelRaw: folder.name,
|
labelRaw: folder.name,
|
||||||
iconEmoji: folder.emoji,
|
iconEmoji: folder.emoji,
|
||||||
iconEmojiUrl: folder.emoji_url,
|
iconEmojiUrl: folder.emoji_url,
|
||||||
iconLetter: folder.name[0]
|
iconLetter: folder.name[0]
|
||||||
}))
|
})) : []
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,13 @@ export const TIMELINES = {
|
||||||
label: 'nav.public_tl',
|
label: 'nav.public_tl',
|
||||||
criteria: ['!private']
|
criteria: ['!private']
|
||||||
},
|
},
|
||||||
|
bubble: {
|
||||||
|
route: 'bubble',
|
||||||
|
anon: true,
|
||||||
|
icon: 'city',
|
||||||
|
label: 'nav.bubble',
|
||||||
|
criteria: ['!private', 'federating', 'supportsBubbleTimeline']
|
||||||
|
},
|
||||||
twkn: {
|
twkn: {
|
||||||
route: 'public-external-timeline',
|
route: 'public-external-timeline',
|
||||||
anon: true,
|
anon: true,
|
||||||
|
|
@ -34,11 +41,11 @@ export const TIMELINES = {
|
||||||
label: 'nav.twkn',
|
label: 'nav.twkn',
|
||||||
criteria: ['!private', 'federating']
|
criteria: ['!private', 'federating']
|
||||||
},
|
},
|
||||||
|
// bookmarks are still technically a timeline so we should show it in the dropdown
|
||||||
bookmarks: {
|
bookmarks: {
|
||||||
route: 'bookmarks',
|
route: 'bookmarks',
|
||||||
icon: 'bookmark',
|
icon: 'bookmark',
|
||||||
label: 'nav.bookmarks',
|
label: 'nav.bookmarks',
|
||||||
criteria: ['!supportsBookmarkFolders']
|
|
||||||
},
|
},
|
||||||
favorites: {
|
favorites: {
|
||||||
routeObject: { name: 'user-profile', query: { tab: 'favorites' } },
|
routeObject: { name: 'user-profile', query: { tab: 'favorites' } },
|
||||||
|
|
@ -53,6 +60,15 @@ export const TIMELINES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ROOT_ITEMS = {
|
export const ROOT_ITEMS = {
|
||||||
|
bookmarks: {
|
||||||
|
route: 'bookmarks',
|
||||||
|
icon: 'bookmark',
|
||||||
|
label: 'nav.bookmarks',
|
||||||
|
// shows bookmarks entry in a better suited location
|
||||||
|
// hides it when bookmark folders are supported since
|
||||||
|
// we show custom component instead of it
|
||||||
|
criteria: ['!supportsBookmarkFolders']
|
||||||
|
},
|
||||||
interactions: {
|
interactions: {
|
||||||
route: 'interactions',
|
route: 'interactions',
|
||||||
icon: 'bell',
|
icon: 'bell',
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faUsers,
|
faUsers,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faCity,
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faComments,
|
faComments,
|
||||||
|
|
@ -25,6 +26,7 @@ import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
|
||||||
library.add(
|
library.add(
|
||||||
faUsers,
|
faUsers,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faCity,
|
||||||
faBookmark,
|
faBookmark,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faComments,
|
faComments,
|
||||||
|
|
@ -65,7 +67,8 @@ const NavPanel = {
|
||||||
followRequestCount: state => state.api.followRequests.length,
|
followRequestCount: state => state.api.followRequests.length,
|
||||||
privateMode: state => state.instance.private,
|
privateMode: state => state.instance.private,
|
||||||
federating: state => state.instance.federating,
|
federating: state => state.instance.federating,
|
||||||
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
|
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
|
||||||
|
bubbleTimeline: state => state.instance.localBubbleInstances.length > 0
|
||||||
}),
|
}),
|
||||||
pinnedList () {
|
pinnedList () {
|
||||||
if (!this.currentUser) {
|
if (!this.currentUser) {
|
||||||
|
|
@ -79,7 +82,9 @@ const NavPanel = {
|
||||||
hasAnnouncements: this.supportsAnnouncements,
|
hasAnnouncements: this.supportsAnnouncements,
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser
|
currentUser: this.currentUser,
|
||||||
|
supportsBubbleTimeline: this.bubbleTimeline,
|
||||||
|
supportsBookmarkFolders: this.bookmarks
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return filterNavigation(
|
return filterNavigation(
|
||||||
|
|
@ -98,6 +103,8 @@ const NavPanel = {
|
||||||
{
|
{
|
||||||
hasChats: this.pleromaChatMessagesAvailable,
|
hasChats: this.pleromaChatMessagesAvailable,
|
||||||
hasAnnouncements: this.supportsAnnouncements,
|
hasAnnouncements: this.supportsAnnouncements,
|
||||||
|
supportsBubbleTimeline: this.bubbleTimeline,
|
||||||
|
supportsBookmarkFolders: this.bookmarks,
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser
|
currentUser: this.currentUser
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-button {
|
.extra-button {
|
||||||
border-left: 1px solid var(--icon);
|
border-left: 1px solid;
|
||||||
|
border-image-source: linear-gradient(to bottom, transparent 0%, var(--icon) var(--__horizontal-gap) calc(100% - var(--__horizontal-gap)), transparent 100%);
|
||||||
|
border-image-slice: 1;
|
||||||
padding-left: calc(var(--__horizontal-gap) - 1px);
|
padding-left: calc(var(--__horizontal-gap) - 1px);
|
||||||
border-right: var(--__horizontal-gap) solid transparent;
|
padding-right: var(--__horizontal-gap);
|
||||||
border-top: var(--__horizontal-gap) solid transparent;
|
padding-top: var(--__horizontal-gap);
|
||||||
border-bottom: var(--__horizontal-gap) solid transparent;
|
padding-bottom: var(--__horizontal-gap);
|
||||||
|
max-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-button {
|
.main-button {
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ import { newImporter } from 'src/services/export_import/export_import.js'
|
||||||
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
||||||
import { init } from 'src/services/theme_data/theme_data_3.service.js'
|
import { init } from 'src/services/theme_data/theme_data_3.service.js'
|
||||||
import {
|
import {
|
||||||
getCssRules,
|
getCssRules
|
||||||
getScopedVersion
|
|
||||||
} from 'src/services/theme_data/css_utils.js'
|
} from 'src/services/theme_data/css_utils.js'
|
||||||
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||||
|
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||||
|
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
||||||
|
|
@ -155,19 +155,23 @@ const AppearanceTab = {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.previewTheme('stock', 'v3')
|
||||||
|
|
||||||
if (window.IntersectionObserver) {
|
if (window.IntersectionObserver) {
|
||||||
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
|
this.intersectionObserver = new IntersectionObserver((entries, observer) => {
|
||||||
entries.forEach(({ target, isIntersecting }) => {
|
entries.forEach(({ target, isIntersecting }) => {
|
||||||
if (!isIntersecting) return
|
if (!isIntersecting) return
|
||||||
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
|
const theme = this.availableStyles.find(x => x.key === target.dataset.themeKey)
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (theme) theme.ready = true
|
if (theme) this.previewTheme(theme.key, theme.version, theme.data)
|
||||||
})
|
})
|
||||||
observer.unobserve(target)
|
observer.unobserve(target)
|
||||||
})
|
})
|
||||||
}, {
|
}, {
|
||||||
root: this.$refs.themeList
|
root: this.$refs.themeList
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
this.availableStyles.forEach(theme => this.previewTheme(theme.key, theme.version, theme.data))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updated () {
|
updated () {
|
||||||
|
|
@ -391,7 +395,6 @@ const AppearanceTab = {
|
||||||
inputRuleset: [...input, paletteRule].filter(x => x),
|
inputRuleset: [...input, paletteRule].filter(x => x),
|
||||||
ultimateBackgroundColor: '#000000',
|
ultimateBackgroundColor: '#000000',
|
||||||
liteMode: true,
|
liteMode: true,
|
||||||
debug: true,
|
|
||||||
onlyNormalState: true
|
onlyNormalState: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -400,7 +403,6 @@ const AppearanceTab = {
|
||||||
inputRuleset: [],
|
inputRuleset: [],
|
||||||
ultimateBackgroundColor: '#000000',
|
ultimateBackgroundColor: '#000000',
|
||||||
liteMode: true,
|
liteMode: true,
|
||||||
debug: true,
|
|
||||||
onlyNormalState: true
|
onlyNormalState: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -409,10 +411,15 @@ const AppearanceTab = {
|
||||||
this.compilationCache[key] = theme3
|
this.compilationCache[key] = theme3
|
||||||
}
|
}
|
||||||
|
|
||||||
return getScopedVersion(
|
|
||||||
getCssRules(theme3.eager),
|
const sheet = createStyleSheet('appearance-tab-previews', 90)
|
||||||
'#theme-preview-' + key
|
sheet.addRule([
|
||||||
).join('\n')
|
'#theme-preview-', key, ' {\n',
|
||||||
|
getCssRules(theme3.eager).join('\n'),
|
||||||
|
'\n}'
|
||||||
|
].join(''))
|
||||||
|
sheet.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,6 @@
|
||||||
:disabled="switchInProgress"
|
:disabled="switchInProgress"
|
||||||
@click="resetTheming"
|
@click="resetTheming"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="previewTheme('stock', 'v3')"
|
|
||||||
/>
|
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
|
||||||
<preview id="theme-preview-stock" />
|
<preview id="theme-preview-stock" />
|
||||||
<h4 class="theme-name">
|
<h4 class="theme-name">
|
||||||
{{ $t('settings.style.stock_theme_used') }}
|
{{ $t('settings.style.stock_theme_used') }}
|
||||||
|
|
@ -61,16 +53,6 @@
|
||||||
:disabled="switchInProgress"
|
:disabled="switchInProgress"
|
||||||
@click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)"
|
@click="style.version === 'v2' ? setTheme(style.key) : setStyle(style.key)"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
|
||||||
<div v-if="style.ready || noIntersectionObserver">
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="previewTheme(style.key, style.version, style.data)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
|
||||||
<preview :id="'theme-preview-' + style.key" />
|
<preview :id="'theme-preview-' + style.key" />
|
||||||
<h4 class="theme-name">
|
<h4 class="theme-name">
|
||||||
{{ style.name }}
|
{{ style.name }}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import InterfaceLanguageSwitcher from 'src/components/interface_language_switche
|
||||||
|
|
||||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||||
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
||||||
|
import { clearCache, cacheKey, emojiCacheKey } from 'src/services/sw/sw.js'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
import {
|
import {
|
||||||
faGlobe
|
faGlobe
|
||||||
|
|
@ -98,6 +99,21 @@ const GeneralTab = {
|
||||||
methods: {
|
methods: {
|
||||||
changeDefaultScope (value) {
|
changeDefaultScope (value) {
|
||||||
this.$store.dispatch('setProfileOption', { name: 'defaultScope', value })
|
this.$store.dispatch('setProfileOption', { name: 'defaultScope', value })
|
||||||
|
},
|
||||||
|
clearCache (key) {
|
||||||
|
clearCache(key)
|
||||||
|
.then(() => {
|
||||||
|
this.$store.dispatch('settingsSaved', { success: true })
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$store.dispatch('settingsSaved', { error })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
clearAssetCache () {
|
||||||
|
this.clearCache(cacheKey)
|
||||||
|
},
|
||||||
|
clearEmojiCache () {
|
||||||
|
this.clearCache(emojiCacheKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,29 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="setting-item"
|
||||||
|
>
|
||||||
|
<h2>{{ $t('settings.cache') }}</h2>
|
||||||
|
<ul class="setting-list">
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click="clearAssetCache"
|
||||||
|
>
|
||||||
|
{{ $t('settings.clear_asset_cache') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
class="btn button-default"
|
||||||
|
@click="clearEmojiCache"
|
||||||
|
>
|
||||||
|
{{ $t('settings.clear_emoji_cache') }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ const SecurityTab = {
|
||||||
user () {
|
user () {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
},
|
},
|
||||||
pleromaBackend () {
|
pleromaExtensionsAvailable () {
|
||||||
return this.$store.state.instance.pleromaBackend
|
return this.$store.state.instance.pleromaExtensionsAvailable
|
||||||
},
|
},
|
||||||
oauthTokens () {
|
oauthTokens () {
|
||||||
return useOAuthTokensStore().tokens.map(oauthToken => {
|
return useOAuthTokensStore().tokens.map(oauthToken => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ref, reactive, computed, watch, watchEffect, provide, getCurrentInstance } from 'vue'
|
import { ref, reactive, computed, watch, provide, getCurrentInstance } from 'vue'
|
||||||
import { useInterfaceStore } from 'src/stores/interface'
|
import { useInterfaceStore } from 'src/stores/interface'
|
||||||
import { get, set, unset, throttle } from 'lodash'
|
import { get, set, unset, throttle } from 'lodash'
|
||||||
|
|
||||||
|
|
@ -19,11 +19,9 @@ import Preview from '../theme_tab/theme_preview.vue'
|
||||||
|
|
||||||
import VirtualDirectivesTab from './virtual_directives_tab.vue'
|
import VirtualDirectivesTab from './virtual_directives_tab.vue'
|
||||||
|
|
||||||
|
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||||
import { init, findColor } from 'src/services/theme_data/theme_data_3.service.js'
|
import { init, findColor } from 'src/services/theme_data/theme_data_3.service.js'
|
||||||
import {
|
import { getCssRules } from 'src/services/theme_data/css_utils.js'
|
||||||
getCssRules,
|
|
||||||
getScopedVersion
|
|
||||||
} from 'src/services/theme_data/css_utils.js'
|
|
||||||
import { serialize } from 'src/services/theme_data/iss_serializer.js'
|
import { serialize } from 'src/services/theme_data/iss_serializer.js'
|
||||||
import { deserializeShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
import { deserializeShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||||
import {
|
import {
|
||||||
|
|
@ -372,6 +370,9 @@ export default {
|
||||||
const path = getPath(component, directive)
|
const path = getPath(component, directive)
|
||||||
|
|
||||||
usedRule = get(real, path) // get real
|
usedRule = get(real, path) // get real
|
||||||
|
if (usedRule === '') {
|
||||||
|
return usedRule
|
||||||
|
}
|
||||||
if (!usedRule) {
|
if (!usedRule) {
|
||||||
usedRule = get(fallback, path)
|
usedRule = get(fallback, path)
|
||||||
}
|
}
|
||||||
|
|
@ -379,7 +380,7 @@ export default {
|
||||||
return postProcess(usedRule)
|
return postProcess(usedRule)
|
||||||
},
|
},
|
||||||
set (value) {
|
set (value) {
|
||||||
if (value) {
|
if (value != null) {
|
||||||
set(allEditedRules.value, getPath(component, directive), value)
|
set(allEditedRules.value, getPath(component, directive), value)
|
||||||
} else {
|
} else {
|
||||||
unset(allEditedRules.value, getPath(component, directive))
|
unset(allEditedRules.value, getPath(component, directive))
|
||||||
|
|
@ -667,7 +668,7 @@ export default {
|
||||||
})
|
})
|
||||||
|
|
||||||
exports.clearStyle = () => {
|
exports.clearStyle = () => {
|
||||||
onImport(interfaceStore().styleDataUsed)
|
onImport(interfaceStore.styleDataUsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.exportStyle = () => {
|
exports.exportStyle = () => {
|
||||||
|
|
@ -685,19 +686,26 @@ export default {
|
||||||
const overallPreviewRules = ref([])
|
const overallPreviewRules = ref([])
|
||||||
exports.overallPreviewRules = overallPreviewRules
|
exports.overallPreviewRules = overallPreviewRules
|
||||||
|
|
||||||
const overallPreviewCssRules = ref([])
|
watch([overallPreviewRules], () => {
|
||||||
watchEffect(throttle(() => {
|
let css = null
|
||||||
try {
|
try {
|
||||||
overallPreviewCssRules.value = getScopedVersion(
|
css = getCssRules(overallPreviewRules.value).map(r => r.replace('html', '&'))
|
||||||
getCssRules(overallPreviewRules.value),
|
|
||||||
'#edited-style-preview'
|
|
||||||
).join('\n')
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}, 500))
|
|
||||||
|
|
||||||
exports.overallPreviewCssRules = overallPreviewCssRules
|
const sheet = createStyleSheet('style-tab-overall-preview', 90)
|
||||||
|
|
||||||
|
sheet.clear()
|
||||||
|
sheet.addRule([
|
||||||
|
'#edited-style-preview {\n',
|
||||||
|
css.join('\n'),
|
||||||
|
'\n}'
|
||||||
|
].join(''))
|
||||||
|
sheet.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
|
})
|
||||||
|
|
||||||
const updateOverallPreview = throttle(() => {
|
const updateOverallPreview = throttle(() => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -721,12 +729,12 @@ export default {
|
||||||
console.error('Could not compile preview theme', e)
|
console.error('Could not compile preview theme', e)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 1000)
|
||||||
//
|
//
|
||||||
// Apart from "hover" we can't really show how component looks like in
|
// Apart from "hover" we can't really show how component looks like in
|
||||||
// certain states, so we have to fake them.
|
// certain states, so we have to fake them.
|
||||||
const simulatePseudoSelectors = (css, prefix) => css
|
const simulatePseudoSelectors = (css, prefix) => css
|
||||||
.replace(prefix, '.component-preview .preview-block')
|
.replace(prefix, '.preview-block')
|
||||||
.replace(':active', '.preview-active')
|
.replace(':active', '.preview-active')
|
||||||
.replace(':hover', '.preview-hover')
|
.replace(':hover', '.preview-hover')
|
||||||
.replace(':active', '.preview-active')
|
.replace(':active', '.preview-active')
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,6 @@
|
||||||
<div class="setting-item heading">
|
<div class="setting-item heading">
|
||||||
<h2> {{ $t('settings.style.themes3.editor.title') }} </h2>
|
<h2> {{ $t('settings.style.themes3.editor.title') }} </h2>
|
||||||
<div class="meta-preview">
|
<div class="meta-preview">
|
||||||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="overallPreviewCssRules"
|
|
||||||
/>
|
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
|
||||||
<Preview id="edited-style-preview" />
|
<Preview id="edited-style-preview" />
|
||||||
<teleport
|
<teleport
|
||||||
v-if="isActive"
|
v-if="isActive"
|
||||||
|
|
@ -155,12 +147,6 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-container">
|
<div class="preview-container">
|
||||||
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="previewCss"
|
|
||||||
/>
|
|
||||||
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<ComponentPreview
|
<ComponentPreview
|
||||||
class="component-preview"
|
class="component-preview"
|
||||||
:show-text="componentHas('Text')"
|
:show-text="componentHas('Text')"
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import {
|
||||||
getCssRules,
|
getCssRules,
|
||||||
getScopedVersion
|
getScopedVersion
|
||||||
} from 'src/services/theme_data/css_utils.js'
|
} from 'src/services/theme_data/css_utils.js'
|
||||||
|
import { createStyleSheet, adoptStyleSheets } from 'src/services/style_setter/style_setter.js'
|
||||||
|
|
||||||
import ColorInput from 'src/components/color_input/color_input.vue'
|
import ColorInput from 'src/components/color_input/color_input.vue'
|
||||||
import RangeInput from 'src/components/range_input/range_input.vue'
|
import RangeInput from 'src/components/range_input/range_input.vue'
|
||||||
|
|
@ -68,7 +69,6 @@ const colorConvert = (color) => {
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
themeV3Preview: [],
|
|
||||||
themeImporter: newImporter({
|
themeImporter: newImporter({
|
||||||
validator: this.importValidator,
|
validator: this.importValidator,
|
||||||
onImport: this.onImport,
|
onImport: this.onImport,
|
||||||
|
|
@ -697,10 +697,16 @@ export default {
|
||||||
liteMode: true
|
liteMode: true
|
||||||
})
|
})
|
||||||
|
|
||||||
this.themeV3Preview = getScopedVersion(
|
const sheet = createStyleSheet('theme-tab-overall-preview', 90)
|
||||||
|
const rule = getScopedVersion(
|
||||||
getCssRules(theme3.eager),
|
getCssRules(theme3.eager),
|
||||||
'#theme-preview'
|
'&'
|
||||||
).join('\n')
|
).join('\n')
|
||||||
|
|
||||||
|
sheet.clear()
|
||||||
|
sheet.addRule('#theme-preview {\n' + rule + '\n}')
|
||||||
|
sheet.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
||||||
|
|
@ -123,12 +123,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- eslint-disable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<component
|
|
||||||
:is="'style'"
|
|
||||||
v-html="themeV3Preview"
|
|
||||||
/>
|
|
||||||
<!-- eslint-enable vue/no-v-html vue/no-v-text-v-html-on-component -->
|
|
||||||
<preview id="theme-preview" />
|
<preview id="theme-preview" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import {
|
||||||
faLock,
|
faLock,
|
||||||
faLockOpen,
|
faLockOpen,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faIgloo,
|
||||||
faTimes,
|
faTimes,
|
||||||
faRetweet,
|
faRetweet,
|
||||||
faReply,
|
faReply,
|
||||||
|
|
@ -43,6 +44,7 @@ import {
|
||||||
library.add(
|
library.add(
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faIgloo,
|
||||||
faLock,
|
faLock,
|
||||||
faLockOpen,
|
faLockOpen,
|
||||||
faTimes,
|
faTimes,
|
||||||
|
|
@ -484,6 +486,8 @@ const Status = {
|
||||||
return 'lock-open'
|
return 'lock-open'
|
||||||
case 'direct':
|
case 'direct':
|
||||||
return 'envelope'
|
return 'envelope'
|
||||||
|
case 'local':
|
||||||
|
return 'igloo'
|
||||||
default:
|
default:
|
||||||
return 'globe'
|
return 'globe'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,4 +102,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.-extra {
|
||||||
|
.action-counter {
|
||||||
|
justify-self: end;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chevron-icon {
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-button {
|
||||||
|
justify-self: end;
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
/>
|
/>
|
||||||
</component>
|
</component>
|
||||||
<span
|
<span
|
||||||
v-if="!extra && button.counter?.(funcArg) > 0"
|
v-if="button.counter?.(funcArg) > 0"
|
||||||
class="action-counter"
|
class="action-counter"
|
||||||
>
|
>
|
||||||
{{ button.counter?.(funcArg) }}
|
{{ button.counter?.(funcArg) }}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,23 @@ const StatusContent = {
|
||||||
hideTallStatus () {
|
hideTallStatus () {
|
||||||
return this.mightHideBecauseTall && !this.showingTall
|
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 () {
|
showingMore () {
|
||||||
return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject)
|
return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@
|
||||||
&.-tall-status {
|
&.-tall-status {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 16em;
|
height: 16em;
|
||||||
overflow: hidden;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.media-body {
|
.media-body {
|
||||||
|
|
@ -82,6 +81,10 @@
|
||||||
mask-composite: exclude;
|
mask-composite: exclude;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.-expanded {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& .tall-status-hider,
|
& .tall-status-hider,
|
||||||
|
|
@ -95,6 +98,13 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-unhider {
|
||||||
|
margin-top: auto;
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.tall-status-hider {
|
.tall-status-hider {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 5em;
|
height: 5em;
|
||||||
|
|
@ -118,6 +128,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggle-button {
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
&.-compact {
|
&.-compact {
|
||||||
align-items: start;
|
align-items: start;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
@ -166,11 +180,11 @@
|
||||||
line-height: inherit;
|
line-height: inherit;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: none;
|
border: none;
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-wrapper {
|
.text-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,9 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:class="{'-tall-status': hideTallStatus}"
|
|
||||||
class="text-wrapper"
|
class="text-wrapper"
|
||||||
|
:class="{'-tall-status': hideTallStatus, '-expanded': showingMore}"
|
||||||
>
|
>
|
||||||
<button
|
|
||||||
v-show="hideTallStatus"
|
|
||||||
class="button-unstyled -link tall-status-hider"
|
|
||||||
:class="{ '-focused': focused }"
|
|
||||||
@click.prevent="toggleShowMore"
|
|
||||||
>
|
|
||||||
{{ $t("general.show_more") }}
|
|
||||||
</button>
|
|
||||||
<RichContent
|
<RichContent
|
||||||
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
v-if="!hideSubjectStatus && !(singleLine && status.summary_raw_html)"
|
||||||
:class="{ '-single-line': singleLine }"
|
:class="{ '-single-line': singleLine }"
|
||||||
|
|
@ -54,45 +46,45 @@
|
||||||
:attentions="status.attentions"
|
:attentions="status.attentions"
|
||||||
@parse-ready="onParseReady"
|
@parse-ready="onParseReady"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
<button
|
v-show="shouldShowToggle"
|
||||||
v-show="hideSubjectStatus"
|
:class="toggleButtonClasses"
|
||||||
class="button-unstyled -link cw-status-hider"
|
|
||||||
@click.prevent="toggleShowMore"
|
|
||||||
>
|
>
|
||||||
{{ $t("status.show_content") }}
|
<button
|
||||||
<FAIcon
|
class="btn button-default toggle-button"
|
||||||
v-if="attachmentTypes.includes('image')"
|
:class="{ '-focused': focused }"
|
||||||
icon="image"
|
:aria-expanded="showingMore"
|
||||||
/>
|
@click.prevent="toggleShowMore"
|
||||||
<FAIcon
|
>
|
||||||
v-if="attachmentTypes.includes('video')"
|
{{ toggleText }}
|
||||||
icon="video"
|
<template v-if="!showingMore">
|
||||||
/>
|
<FAIcon
|
||||||
<FAIcon
|
v-if="attachmentTypes.includes('image')"
|
||||||
v-if="attachmentTypes.includes('audio')"
|
icon="image"
|
||||||
icon="music"
|
/>
|
||||||
/>
|
<FAIcon
|
||||||
<FAIcon
|
v-if="attachmentTypes.includes('video')"
|
||||||
v-if="attachmentTypes.includes('unknown')"
|
icon="video"
|
||||||
icon="file"
|
/>
|
||||||
/>
|
<FAIcon
|
||||||
<FAIcon
|
v-if="attachmentTypes.includes('audio')"
|
||||||
v-if="status.poll && status.poll.options"
|
icon="music"
|
||||||
icon="poll-h"
|
/>
|
||||||
/>
|
<FAIcon
|
||||||
<FAIcon
|
v-if="attachmentTypes.includes('unknown')"
|
||||||
v-if="status.card"
|
icon="file"
|
||||||
icon="link"
|
/>
|
||||||
/>
|
<FAIcon
|
||||||
</button>
|
v-if="status.poll && status.poll.options"
|
||||||
<button
|
icon="poll-h"
|
||||||
v-show="showingMore && !fullContent"
|
/>
|
||||||
class="button-unstyled -link status-unhider"
|
<FAIcon
|
||||||
@click.prevent="toggleShowMore"
|
v-if="status.card"
|
||||||
>
|
icon="link"
|
||||||
{{ tallStatus ? $t("general.show_less") : $t("status.hide_content") }}
|
/>
|
||||||
</button>
|
</template>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<slot v-if="!hideSubjectStatus" />
|
<slot v-if="!hideSubjectStatus" />
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ export const timelineNames = (supportsBookmarkFolders) => {
|
||||||
dms: 'nav.dms',
|
dms: 'nav.dms',
|
||||||
'public-timeline': 'nav.public_tl',
|
'public-timeline': 'nav.public_tl',
|
||||||
'public-external-timeline': 'nav.twkn',
|
'public-external-timeline': 'nav.twkn',
|
||||||
quotes: 'nav.quotes'
|
quotes: 'nav.quotes',
|
||||||
|
bubble: 'nav.bubble'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +59,8 @@ const TimelineMenu = {
|
||||||
currentUser: state => state.users.currentUser,
|
currentUser: state => state.users.currentUser,
|
||||||
privateMode: state => state.instance.private,
|
privateMode: state => state.instance.private,
|
||||||
federating: state => state.instance.federating,
|
federating: state => state.instance.federating,
|
||||||
bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable
|
bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable,
|
||||||
|
bubbleTimeline: state => state.instance.localBubbleInstances.length > 0
|
||||||
}),
|
}),
|
||||||
timelinesList () {
|
timelinesList () {
|
||||||
return filterNavigation(
|
return filterNavigation(
|
||||||
|
|
@ -68,7 +70,8 @@ const TimelineMenu = {
|
||||||
isFederating: this.federating,
|
isFederating: this.federating,
|
||||||
isPrivate: this.privateMode,
|
isPrivate: this.privateMode,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
supportsBookmarkFolders: this.bookmarkFolders
|
supportsBookmarkFolders: this.bookmarkFolders,
|
||||||
|
supportsBubbleTimeline: this.bubbleTimeline
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,10 @@ export default {
|
||||||
},
|
},
|
||||||
showModerationMenu () {
|
showModerationMenu () {
|
||||||
const privileges = this.loggedIn.privileges
|
const privileges = this.loggedIn.privileges
|
||||||
return this.loggedIn.role === 'admin' || privileges.includes('users_manage_activation_state') || privileges.includes('users_delete') || privileges.includes('users_manage_tags')
|
return this.loggedIn.role === 'admin' ||
|
||||||
|
privileges.includes('users_manage_activation_state') ||
|
||||||
|
privileges.includes('users_delete') ||
|
||||||
|
privileges.includes('users_manage_tags')
|
||||||
},
|
},
|
||||||
hasNote () {
|
hasNote () {
|
||||||
return this.relationship.note
|
return this.relationship.note
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ const UserProfile = {
|
||||||
return this.isUs || !this.user.hide_followers
|
return this.isUs || !this.user.hide_followers
|
||||||
},
|
},
|
||||||
favoritesTabVisible () {
|
favoritesTabVisible () {
|
||||||
return this.isUs || !this.user.hide_favorites
|
return this.isUs || (this.$store.state.instance.pleromaPublicFavouritesAvailable && !this.user.hide_favorites)
|
||||||
},
|
},
|
||||||
formattedBirthday () {
|
formattedBirthday () {
|
||||||
const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale)
|
const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale)
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@
|
||||||
"flash_security": "Note that this can be potentially dangerous since Flash content is still arbitrary code.",
|
"flash_security": "Note that this can be potentially dangerous since Flash content is still arbitrary code.",
|
||||||
"flash_fail": "Failed to load flash content, see console for details.",
|
"flash_fail": "Failed to load flash content, see console for details.",
|
||||||
"scope_in_timeline": {
|
"scope_in_timeline": {
|
||||||
|
"local": "Non-federated",
|
||||||
"direct": "Direct",
|
"direct": "Direct",
|
||||||
"private": "Followers-only",
|
"private": "Followers-only",
|
||||||
"public": "Public",
|
"public": "Public",
|
||||||
|
|
@ -171,6 +172,7 @@
|
||||||
"interactions": "Interactions",
|
"interactions": "Interactions",
|
||||||
"dms": "Direct messages",
|
"dms": "Direct messages",
|
||||||
"public_tl": "Public timeline",
|
"public_tl": "Public timeline",
|
||||||
|
"bubble": "Bubble timeline",
|
||||||
"timeline": "Timeline",
|
"timeline": "Timeline",
|
||||||
"home_timeline": "Home timeline",
|
"home_timeline": "Home timeline",
|
||||||
"twkn": "Known Network",
|
"twkn": "Known Network",
|
||||||
|
|
@ -289,7 +291,8 @@
|
||||||
"text/plain": "Plain text",
|
"text/plain": "Plain text",
|
||||||
"text/html": "HTML",
|
"text/html": "HTML",
|
||||||
"text/markdown": "Markdown",
|
"text/markdown": "Markdown",
|
||||||
"text/bbcode": "BBCode"
|
"text/bbcode": "BBCode",
|
||||||
|
"text/x.misskeymarkdown": "MFM"
|
||||||
},
|
},
|
||||||
"content_type_selection": "Post format",
|
"content_type_selection": "Post format",
|
||||||
"content_warning": "Subject (optional)",
|
"content_warning": "Subject (optional)",
|
||||||
|
|
@ -1088,7 +1091,10 @@
|
||||||
"reset_value": "Reset",
|
"reset_value": "Reset",
|
||||||
"reset_value_tooltip": "Reset draft",
|
"reset_value_tooltip": "Reset draft",
|
||||||
"hard_reset_value": "Hard reset",
|
"hard_reset_value": "Hard reset",
|
||||||
"hard_reset_value_tooltip": "Remove setting from storage, forcing use of default value"
|
"hard_reset_value_tooltip": "Remove setting from storage, forcing use of default value",
|
||||||
|
"cache": "Cache",
|
||||||
|
"clear_asset_cache": "Clear asset cache",
|
||||||
|
"clear_emoji_cache": "Clear emoji cache"
|
||||||
},
|
},
|
||||||
"admin_dash": {
|
"admin_dash": {
|
||||||
"window_title": "Administration",
|
"window_title": "Administration",
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,7 @@ const api = {
|
||||||
statusId = false,
|
statusId = false,
|
||||||
bookmarkFolderId = false
|
bookmarkFolderId = false
|
||||||
}) {
|
}) {
|
||||||
|
if (timeline === 'favourites' && !store.rootState.instance.pleromaPublicFavouritesAvailable) return
|
||||||
if (store.state.fetchers[timeline]) return
|
if (store.state.fetchers[timeline]) return
|
||||||
|
|
||||||
const fetcher = store.state.backendInteractor.startFetchingTimeline({
|
const fetcher = store.state.backendInteractor.startFetchingTimeline({
|
||||||
|
|
@ -281,6 +282,7 @@ const api = {
|
||||||
// Bookmark folders
|
// Bookmark folders
|
||||||
startFetchingBookmarkFolders (store) {
|
startFetchingBookmarkFolders (store) {
|
||||||
if (store.state.fetchers.bookmarkFolders) return
|
if (store.state.fetchers.bookmarkFolders) return
|
||||||
|
if (!store.rootState.instance.pleromaBookmarkFoldersAvailable) return
|
||||||
const fetcher = store.state.backendInteractor.startFetchingBookmarkFolders({ store })
|
const fetcher = store.state.backendInteractor.startFetchingBookmarkFolders({ store })
|
||||||
store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher })
|
store.commit('addFetcher', { fetcherName: 'bookmarkFolders', fetcher })
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
|
||||||
|
|
||||||
const PASSWORD_STRATEGY = 'password'
|
|
||||||
const TOKEN_STRATEGY = 'token'
|
|
||||||
|
|
||||||
// MFA strategies
|
|
||||||
const TOTP_STRATEGY = 'totp'
|
|
||||||
const RECOVERY_STRATEGY = 'recovery'
|
|
||||||
|
|
||||||
// initial state
|
|
||||||
const state = {
|
|
||||||
settings: {},
|
|
||||||
strategy: PASSWORD_STRATEGY,
|
|
||||||
initStrategy: PASSWORD_STRATEGY // default strategy from config
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetState = (state) => {
|
|
||||||
state.strategy = state.initStrategy
|
|
||||||
state.settings = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
const getters = {
|
|
||||||
settings: (state) => {
|
|
||||||
return state.settings
|
|
||||||
},
|
|
||||||
requiredPassword: (state) => {
|
|
||||||
return state.strategy === PASSWORD_STRATEGY
|
|
||||||
},
|
|
||||||
requiredToken: (state) => {
|
|
||||||
return state.strategy === TOKEN_STRATEGY
|
|
||||||
},
|
|
||||||
requiredTOTP: (state) => {
|
|
||||||
return state.strategy === TOTP_STRATEGY
|
|
||||||
},
|
|
||||||
requiredRecovery: (state) => {
|
|
||||||
return state.strategy === RECOVERY_STRATEGY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
const mutations = {
|
|
||||||
setInitialStrategy (state, strategy) {
|
|
||||||
if (strategy) {
|
|
||||||
state.initStrategy = strategy
|
|
||||||
state.strategy = strategy
|
|
||||||
}
|
|
||||||
},
|
|
||||||
requirePassword (state) {
|
|
||||||
state.strategy = PASSWORD_STRATEGY
|
|
||||||
},
|
|
||||||
requireToken (state) {
|
|
||||||
state.strategy = TOKEN_STRATEGY
|
|
||||||
},
|
|
||||||
requireMFA (state, { settings }) {
|
|
||||||
state.settings = settings
|
|
||||||
state.strategy = TOTP_STRATEGY // default strategy of MFA
|
|
||||||
},
|
|
||||||
requireRecovery (state) {
|
|
||||||
state.strategy = RECOVERY_STRATEGY
|
|
||||||
},
|
|
||||||
requireTOTP (state) {
|
|
||||||
state.strategy = TOTP_STRATEGY
|
|
||||||
},
|
|
||||||
abortMFA (state) {
|
|
||||||
resetState(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
const actions = {
|
|
||||||
|
|
||||||
async login ({ state, dispatch }, { access_token: accessToken }) {
|
|
||||||
useOAuthStore().setToken(accessToken)
|
|
||||||
await dispatch('loginUser', accessToken, { root: true })
|
|
||||||
resetState(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
namespaced: true,
|
|
||||||
state,
|
|
||||||
getters,
|
|
||||||
mutations,
|
|
||||||
actions
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ import api from './api.js'
|
||||||
import config from './config.js'
|
import config from './config.js'
|
||||||
import profileConfig from './profileConfig.js'
|
import profileConfig from './profileConfig.js'
|
||||||
import adminSettings from './adminSettings.js'
|
import adminSettings from './adminSettings.js'
|
||||||
import authFlow from './auth_flow.js'
|
|
||||||
import drafts from './drafts.js'
|
import drafts from './drafts.js'
|
||||||
import chats from './chats.js'
|
import chats from './chats.js'
|
||||||
|
|
||||||
|
|
@ -19,7 +18,6 @@ export default {
|
||||||
config,
|
config,
|
||||||
profileConfig,
|
profileConfig,
|
||||||
adminSettings,
|
adminSettings,
|
||||||
authFlow,
|
|
||||||
drafts,
|
drafts,
|
||||||
chats
|
chats
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ const defaultState = {
|
||||||
emoji: {},
|
emoji: {},
|
||||||
emojiFetched: false,
|
emojiFetched: false,
|
||||||
unicodeEmojiAnnotations: {},
|
unicodeEmojiAnnotations: {},
|
||||||
pleromaBackend: true,
|
pleromaExtensionsAvailable: true,
|
||||||
postFormats: [],
|
postFormats: [],
|
||||||
restrictedNicknames: [],
|
restrictedNicknames: [],
|
||||||
safeDM: true,
|
safeDM: true,
|
||||||
|
|
@ -156,6 +156,8 @@ const defaultState = {
|
||||||
pleromaChatMessagesAvailable: false,
|
pleromaChatMessagesAvailable: false,
|
||||||
pleromaCustomEmojiReactionsAvailable: false,
|
pleromaCustomEmojiReactionsAvailable: false,
|
||||||
pleromaBookmarkFoldersAvailable: false,
|
pleromaBookmarkFoldersAvailable: false,
|
||||||
|
pleromaPublicFavouritesAvailable: true,
|
||||||
|
statusNotificationTypeAvailable: true,
|
||||||
gopherAvailable: false,
|
gopherAvailable: false,
|
||||||
mediaProxyAvailable: false,
|
mediaProxyAvailable: false,
|
||||||
suggestionsEnabled: false,
|
suggestionsEnabled: false,
|
||||||
|
|
@ -163,6 +165,7 @@ const defaultState = {
|
||||||
quotingAvailable: false,
|
quotingAvailable: false,
|
||||||
groupActorAvailable: false,
|
groupActorAvailable: false,
|
||||||
blockExpiration: false,
|
blockExpiration: false,
|
||||||
|
localBubbleInstances: [], // Akkoma
|
||||||
|
|
||||||
// Html stuff
|
// Html stuff
|
||||||
instanceSpecificPanelContent: '',
|
instanceSpecificPanelContent: '',
|
||||||
|
|
@ -341,7 +344,10 @@ const instance = {
|
||||||
|
|
||||||
async getCustomEmoji ({ commit, state }) {
|
async getCustomEmoji ({ commit, state }) {
|
||||||
try {
|
try {
|
||||||
const res = await window.fetch('/api/pleroma/emoji.json')
|
let res = await window.fetch('/api/v1/pleroma/emoji')
|
||||||
|
if (!res.ok) {
|
||||||
|
res = await window.fetch('/api/pleroma/emoji.json')
|
||||||
|
}
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const result = await res.json()
|
const result = await res.json()
|
||||||
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
|
const values = Array.isArray(result) ? Object.assign({}, ...result) : result
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export const defaultState = () => ({
|
||||||
conversationsObject: {},
|
conversationsObject: {},
|
||||||
maxId: 0,
|
maxId: 0,
|
||||||
favorites: new Set(),
|
favorites: new Set(),
|
||||||
|
pleromaScrobblesAvailable: true, // not reported in nodeinfo
|
||||||
timelines: {
|
timelines: {
|
||||||
mentions: emptyTl(),
|
mentions: emptyTl(),
|
||||||
public: emptyTl(),
|
public: emptyTl(),
|
||||||
|
|
@ -50,7 +51,8 @@ export const defaultState = () => ({
|
||||||
tag: emptyTl(),
|
tag: emptyTl(),
|
||||||
dms: emptyTl(),
|
dms: emptyTl(),
|
||||||
bookmarks: emptyTl(),
|
bookmarks: emptyTl(),
|
||||||
list: emptyTl()
|
list: emptyTl(),
|
||||||
|
bubble: emptyTl()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -108,12 +110,21 @@ const sortTimeline = (timeline) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getLatestScrobble = (state, user) => {
|
const getLatestScrobble = (state, user) => {
|
||||||
|
const scrobblesSupport = state.pleromaScrobblesAvailable
|
||||||
|
if (!scrobblesSupport) return
|
||||||
|
|
||||||
if (state.scrobblesNextFetch[user.id] && state.scrobblesNextFetch[user.id] > Date.now()) {
|
if (state.scrobblesNextFetch[user.id] && state.scrobblesNextFetch[user.id] > Date.now()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
state.scrobblesNextFetch[user.id] = Date.now() + 24 * 60 * 60 * 1000
|
state.scrobblesNextFetch[user.id] = Date.now() + 24 * 60 * 60 * 1000
|
||||||
|
if (!scrobblesSupport) return
|
||||||
apiService.fetchScrobbles({ accountId: user.id }).then((scrobbles) => {
|
apiService.fetchScrobbles({ accountId: user.id }).then((scrobbles) => {
|
||||||
|
if (scrobbles?.error) {
|
||||||
|
state.pleromaScrobblesAvailable = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (scrobbles.length > 0) {
|
if (scrobbles.length > 0) {
|
||||||
user.latestScrobble = scrobbles[0]
|
user.latestScrobble = scrobbles[0]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,7 @@ const users = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const commit = store.commit
|
const commit = store.commit
|
||||||
const dispatch = store.dispatch
|
const dispatch = store.dispatch
|
||||||
|
const rootState = store.rootState
|
||||||
commit('beginLogin')
|
commit('beginLogin')
|
||||||
store.rootState.api.backendInteractor.verifyCredentials(accessToken)
|
store.rootState.api.backendInteractor.verifyCredentials(accessToken)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
|
|
@ -673,8 +674,10 @@ const users = {
|
||||||
// Start fetching notifications
|
// Start fetching notifications
|
||||||
dispatch('startFetchingNotifications')
|
dispatch('startFetchingNotifications')
|
||||||
|
|
||||||
// Start fetching chats
|
if (rootState.instance.pleromaChatMessagesAvailable) {
|
||||||
dispatch('startFetchingChats')
|
// Start fetching chats
|
||||||
|
dispatch('startFetchingChats')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch('startFetchingLists')
|
dispatch('startFetchingLists')
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const TAG_USER_URL = '/api/pleroma/admin/users/tag'
|
||||||
const PERMISSION_GROUP_URL = (screenName, right) => `/api/pleroma/admin/users/${screenName}/permission_group/${right}`
|
const PERMISSION_GROUP_URL = (screenName, right) => `/api/pleroma/admin/users/${screenName}/permission_group/${right}`
|
||||||
const ACTIVATE_USER_URL = '/api/pleroma/admin/users/activate'
|
const ACTIVATE_USER_URL = '/api/pleroma/admin/users/activate'
|
||||||
const DEACTIVATE_USER_URL = '/api/pleroma/admin/users/deactivate'
|
const DEACTIVATE_USER_URL = '/api/pleroma/admin/users/deactivate'
|
||||||
const ADMIN_USERS_URL = '/api/pleroma/admin/users'
|
const ADMIN_USERS_URL = '/api/v1/pleroma/admin/users'
|
||||||
const SUGGESTIONS_URL = '/api/v1/suggestions'
|
const SUGGESTIONS_URL = '/api/v1/suggestions'
|
||||||
const NOTIFICATION_SETTINGS_URL = '/api/pleroma/notification_settings'
|
const NOTIFICATION_SETTINGS_URL = '/api/pleroma/notification_settings'
|
||||||
const NOTIFICATION_READ_URL = '/api/v1/pleroma/notifications/read'
|
const NOTIFICATION_READ_URL = '/api/v1/pleroma/notifications/read'
|
||||||
|
|
@ -61,6 +61,7 @@ const MASTODON_LIST_TIMELINE_URL = id => `/api/v1/timelines/list/${id}`
|
||||||
const MASTODON_LIST_ACCOUNTS_URL = id => `/api/v1/lists/${id}/accounts`
|
const MASTODON_LIST_ACCOUNTS_URL = id => `/api/v1/lists/${id}/accounts`
|
||||||
const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}`
|
const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}`
|
||||||
const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks'
|
const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks'
|
||||||
|
const AKKOMA_BUBBLE_TIMELINE_URL = '/api/v1/timelines/bubble'
|
||||||
const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/'
|
const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/'
|
||||||
const MASTODON_USER_MUTES_URL = '/api/v1/mutes/'
|
const MASTODON_USER_MUTES_URL = '/api/v1/mutes/'
|
||||||
const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block`
|
const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block`
|
||||||
|
|
@ -99,7 +100,7 @@ const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}`
|
||||||
const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages`
|
const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages`
|
||||||
const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
|
const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
|
||||||
const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}`
|
const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}`
|
||||||
const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports'
|
const PLEROMA_ADMIN_REPORTS = '/api/v1/pleroma/admin/reports'
|
||||||
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
|
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
|
||||||
const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
|
const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
|
||||||
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
|
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
|
||||||
|
|
@ -111,10 +112,10 @@ const PLEROMA_USER_FAVORITES_TIMELINE_URL = id => `/api/v1/pleroma/accounts/${id
|
||||||
const PLEROMA_BOOKMARK_FOLDERS_URL = '/api/v1/pleroma/bookmark_folders'
|
const PLEROMA_BOOKMARK_FOLDERS_URL = '/api/v1/pleroma/bookmark_folders'
|
||||||
const PLEROMA_BOOKMARK_FOLDER_URL = id => `/api/v1/pleroma/bookmark_folders/${id}`
|
const PLEROMA_BOOKMARK_FOLDER_URL = id => `/api/v1/pleroma/bookmark_folders/${id}`
|
||||||
|
|
||||||
const PLEROMA_ADMIN_CONFIG_URL = '/api/pleroma/admin/config'
|
const PLEROMA_ADMIN_CONFIG_URL = '/api/v1/pleroma/admin/config'
|
||||||
const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/pleroma/admin/config/descriptions'
|
const PLEROMA_ADMIN_DESCRIPTIONS_URL = '/api/v1/pleroma/admin/config/descriptions'
|
||||||
const PLEROMA_ADMIN_FRONTENDS_URL = '/api/pleroma/admin/frontends'
|
const PLEROMA_ADMIN_FRONTENDS_URL = '/api/v1/pleroma/admin/frontends'
|
||||||
const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/pleroma/admin/frontends/install'
|
const PLEROMA_ADMIN_FRONTENDS_INSTALL_URL = '/api/v1/pleroma/admin/frontends/install'
|
||||||
|
|
||||||
const PLEROMA_EMOJI_RELOAD_URL = '/api/pleroma/admin/reload_emoji'
|
const PLEROMA_EMOJI_RELOAD_URL = '/api/pleroma/admin/reload_emoji'
|
||||||
const PLEROMA_EMOJI_IMPORT_FS_URL = '/api/pleroma/emoji/packs/import'
|
const PLEROMA_EMOJI_IMPORT_FS_URL = '/api/pleroma/emoji/packs/import'
|
||||||
|
|
@ -714,7 +715,8 @@ const fetchTimeline = ({
|
||||||
publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL,
|
publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL,
|
||||||
tag: MASTODON_TAG_TIMELINE_URL,
|
tag: MASTODON_TAG_TIMELINE_URL,
|
||||||
bookmarks: MASTODON_BOOKMARK_TIMELINE_URL,
|
bookmarks: MASTODON_BOOKMARK_TIMELINE_URL,
|
||||||
quotes: PLEROMA_STATUS_QUOTES_URL
|
quotes: PLEROMA_STATUS_QUOTES_URL,
|
||||||
|
bubble: AKKOMA_BUBBLE_TIMELINE_URL
|
||||||
}
|
}
|
||||||
const isNotifications = timeline === 'notifications'
|
const isNotifications = timeline === 'notifications'
|
||||||
const params = []
|
const params = []
|
||||||
|
|
@ -764,7 +766,7 @@ const fetchTimeline = ({
|
||||||
if (replyVisibility !== 'all') {
|
if (replyVisibility !== 'all') {
|
||||||
params.push(['reply_visibility', replyVisibility])
|
params.push(['reply_visibility', replyVisibility])
|
||||||
}
|
}
|
||||||
if (includeTypes.length > 0) {
|
if (includeTypes.size > 0) {
|
||||||
includeTypes.forEach(type => {
|
includeTypes.forEach(type => {
|
||||||
params.push(['include_types[]', type])
|
params.push(['include_types[]', type])
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,32 @@ export const getContrastRatioLayers = (text, layers, bedrock) => {
|
||||||
return getContrastRatio(alphaBlendLayers(bedrock, layers), text)
|
return getContrastRatio(alphaBlendLayers(bedrock, layers), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blending of two solid colors with a user-defined operator: origin +- value
|
||||||
|
*
|
||||||
|
* @param {Object} origin - base color
|
||||||
|
* @param {Object} value - modification argument
|
||||||
|
* @param {string} operator - math operator to use
|
||||||
|
*/
|
||||||
|
export const arithmeticBlend = (origin, value, operator) => {
|
||||||
|
const func = (a, b) => {
|
||||||
|
switch (operator) {
|
||||||
|
case '+':
|
||||||
|
return Math.min(a + b, 255)
|
||||||
|
case '-':
|
||||||
|
return Math.max(a - b, 0)
|
||||||
|
default:
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
r: func(origin.r, value.r),
|
||||||
|
g: func(origin.g, value.g),
|
||||||
|
b: func(origin.b, value.b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This performs alpha blending between solid background and semi-transparent foreground
|
* This performs alpha blending between solid background and semi-transparent foreground
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ export const parseUser = (data) => {
|
||||||
|
|
||||||
output.bot = data.bot
|
output.bot = data.bot
|
||||||
|
|
||||||
|
output.privileges = []
|
||||||
|
|
||||||
if (data.pleroma) {
|
if (data.pleroma) {
|
||||||
if (data.pleroma.settings_store) {
|
if (data.pleroma.settings_store) {
|
||||||
output.storage = data.pleroma.settings_store['pleroma-fe']
|
output.storage = data.pleroma.settings_store['pleroma-fe']
|
||||||
|
|
@ -317,20 +319,18 @@ export const parseStatus = (data) => {
|
||||||
|
|
||||||
output.edited_at = data.edited_at
|
output.edited_at = data.edited_at
|
||||||
|
|
||||||
|
const { pleroma } = data
|
||||||
|
|
||||||
if (data.pleroma) {
|
if (data.pleroma) {
|
||||||
const { pleroma } = data
|
|
||||||
output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content
|
output.text = pleroma.content ? data.pleroma.content['text/plain'] : data.content
|
||||||
output.summary = pleroma.spoiler_text ? data.pleroma.spoiler_text['text/plain'] : data.spoiler_text
|
output.summary = pleroma.spoiler_text ? data.pleroma.spoiler_text['text/plain'] : data.spoiler_text
|
||||||
output.statusnet_conversation_id = data.pleroma.conversation_id
|
output.statusnet_conversation_id = data.pleroma.conversation_id
|
||||||
output.is_local = pleroma.local
|
output.is_local = pleroma.local
|
||||||
output.in_reply_to_screen_name = data.pleroma.in_reply_to_account_acct
|
output.in_reply_to_screen_name = pleroma.in_reply_to_account_acct
|
||||||
output.thread_muted = pleroma.thread_muted
|
output.thread_muted = pleroma.thread_muted
|
||||||
output.emoji_reactions = pleroma.emoji_reactions
|
output.emoji_reactions = pleroma.emoji_reactions
|
||||||
output.parent_visible = pleroma.parent_visible === undefined ? true : pleroma.parent_visible
|
output.parent_visible = pleroma.parent_visible === undefined ? true : pleroma.parent_visible
|
||||||
output.quote = pleroma.quote ? parseStatus(pleroma.quote) : undefined
|
output.quote_visible = pleroma.quote_visible || true
|
||||||
output.quote_id = pleroma.quote_id ? pleroma.quote_id : (output.quote ? output.quote.id : undefined)
|
|
||||||
output.quote_url = pleroma.quote_url
|
|
||||||
output.quote_visible = pleroma.quote_visible
|
|
||||||
output.quotes_count = pleroma.quotes_count
|
output.quotes_count = pleroma.quotes_count
|
||||||
output.bookmark_folder_id = pleroma.bookmark_folder
|
output.bookmark_folder_id = pleroma.bookmark_folder
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -338,6 +338,12 @@ export const parseStatus = (data) => {
|
||||||
output.summary = data.spoiler_text
|
output.summary = data.spoiler_text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const quoteRaw = pleroma?.quote || data.quote
|
||||||
|
const quoteData = quoteRaw ? parseStatus(quoteRaw) : undefined
|
||||||
|
output.quote = quoteData
|
||||||
|
output.quote_id = data.quote?.id ?? data.quote_id ?? quoteData?.id ?? pleroma.quote_id
|
||||||
|
output.quote_url = data.quote?.url ?? quoteData?.url ?? pleroma.quote_url
|
||||||
|
|
||||||
output.in_reply_to_status_id = data.in_reply_to_id
|
output.in_reply_to_status_id = data.in_reply_to_id
|
||||||
output.in_reply_to_user_id = data.in_reply_to_account_id
|
output.in_reply_to_user_id = data.in_reply_to_account_id
|
||||||
output.replies_count = data.replies_count
|
output.replies_count = data.replies_count
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,13 @@ import { useInterfaceStore } from 'src/stores/interface.js'
|
||||||
import apiService from '../api/api.service.js'
|
import apiService from '../api/api.service.js'
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
||||||
|
|
||||||
|
const update = ({ store, notifications, older }) => {
|
||||||
|
store.dispatch('addNewNotifications', { notifications, older })
|
||||||
|
}
|
||||||
|
//
|
||||||
// For using include_types when fetching notifications.
|
// For using include_types when fetching notifications.
|
||||||
// Note: chat_mention excluded as pleroma-fe polls them separately
|
// Note: chat_mention excluded as pleroma-fe polls them separately
|
||||||
const mastoApiNotificationTypes = [
|
const mastoApiNotificationTypes = new Set([
|
||||||
'mention',
|
'mention',
|
||||||
'status',
|
'status',
|
||||||
'favourite',
|
'favourite',
|
||||||
|
|
@ -14,21 +18,22 @@ const mastoApiNotificationTypes = [
|
||||||
'move',
|
'move',
|
||||||
'poll',
|
'poll',
|
||||||
'pleroma:emoji_reaction',
|
'pleroma:emoji_reaction',
|
||||||
'pleroma:chat_mention',
|
'pleroma:report',
|
||||||
'pleroma:report'
|
'test'
|
||||||
]
|
])
|
||||||
|
|
||||||
const update = ({ store, notifications, older }) => {
|
|
||||||
store.dispatch('addNewNotifications', { notifications, older })
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
|
||||||
|
|
||||||
const args = { credentials }
|
const args = { credentials }
|
||||||
const { getters } = store
|
const { getters } = store
|
||||||
const rootState = store.rootState || store.state
|
const rootState = store.rootState || store.state
|
||||||
const timelineData = rootState.notifications
|
const timelineData = rootState.notifications
|
||||||
const hideMutedPosts = getters.mergedConfig.hideMutedPosts
|
const hideMutedPosts = getters.mergedConfig.hideMutedPosts
|
||||||
|
|
||||||
|
if (rootState.instance.pleromaChatMessagesAvailable) {
|
||||||
|
mastoApiNotificationTypes.add('pleroma:chat_mention')
|
||||||
|
}
|
||||||
|
|
||||||
args.includeTypes = mastoApiNotificationTypes
|
args.includeTypes = mastoApiNotificationTypes
|
||||||
args.withMuted = !hideMutedPosts
|
args.withMuted = !hideMutedPosts
|
||||||
|
|
||||||
|
|
@ -72,7 +77,17 @@ const fetchNotifications = ({ store, args, older }) => {
|
||||||
return apiService.fetchTimeline(args)
|
return apiService.fetchTimeline(args)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
throw new Error(`${response.status} ${response.statusText}`)
|
if (response.status === 400 && response.statusText.includes('Invalid value for enum')) {
|
||||||
|
response
|
||||||
|
.statusText
|
||||||
|
.matchAll(/(\w+) - Invalid value for enum./g)
|
||||||
|
.toArray()
|
||||||
|
.map(x => x[1])
|
||||||
|
.forEach(x => mastoApiNotificationTypes.delete(x))
|
||||||
|
return fetchNotifications({ store, args, older })
|
||||||
|
} else {
|
||||||
|
throw new Error(`${response.status} ${response.statusText}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const notifications = response.data
|
const notifications = response.data
|
||||||
update({ store, notifications, older })
|
update({ store, notifications, older })
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,76 @@
|
||||||
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js'
|
||||||
import { getCssRules } from '../theme_data/css_utils.js'
|
import { getCssRules } from '../theme_data/css_utils.js'
|
||||||
import { defaultState } from 'src/modules/default_config_state.js'
|
import { defaultState } from 'src/modules/default_config_state.js'
|
||||||
import { chunk } from 'lodash'
|
import { chunk, throttle } from 'lodash'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
|
|
||||||
// On platforms where this is not supported, it will return undefined
|
// On platforms where this is not supported, it will return undefined
|
||||||
// Otherwise it will return an array
|
// Otherwise it will return an array
|
||||||
const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets
|
const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets
|
||||||
|
|
||||||
const createStyleSheet = (id) => {
|
const stylesheets = {}
|
||||||
if (supportsAdoptedStyleSheets) {
|
|
||||||
return {
|
export const createStyleSheet = (id, priority = 1000) => {
|
||||||
el: null,
|
if (stylesheets[id]) return stylesheets[id]
|
||||||
sheet: new CSSStyleSheet(),
|
const newStyleSheet = {
|
||||||
rules: []
|
rules: [],
|
||||||
|
ready: false,
|
||||||
|
priority,
|
||||||
|
clear () {
|
||||||
|
this.rules = []
|
||||||
|
},
|
||||||
|
addRule (rule) {
|
||||||
|
let newRule = rule
|
||||||
|
if (!CSS.supports?.('backdrop-filter', 'blur()')) {
|
||||||
|
newRule = newRule.replace(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter
|
||||||
|
}
|
||||||
|
this.rules.push(
|
||||||
|
newRule
|
||||||
|
.replace(/var\(--shadowFilter\)[^;]*;/g, '') // Remove shadowFilter references
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = document.getElementById(id)
|
stylesheets[id] = newStyleSheet
|
||||||
// Clear all rules in it
|
return newStyleSheet
|
||||||
for (let i = el.sheet.cssRules.length - 1; i >= 0; --i) {
|
|
||||||
el.sheet.deleteRule(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
el,
|
|
||||||
sheet: el.sheet,
|
|
||||||
rules: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EAGER_STYLE_ID = 'pleroma-eager-styles'
|
|
||||||
const LAZY_STYLE_ID = 'pleroma-lazy-styles'
|
|
||||||
|
|
||||||
const adoptStyleSheets = (styles) => {
|
export const adoptStyleSheets = throttle(() => {
|
||||||
if (supportsAdoptedStyleSheets) {
|
if (supportsAdoptedStyleSheets) {
|
||||||
document.adoptedStyleSheets = styles.map(s => s.sheet)
|
document.adoptedStyleSheets = Object
|
||||||
|
.values(stylesheets)
|
||||||
|
.filter(x => x.ready)
|
||||||
|
.sort((a, b) => a.priority - b.priority)
|
||||||
|
.map(sheet => {
|
||||||
|
const css = new CSSStyleSheet()
|
||||||
|
sheet.rules.forEach(r => css.insertRule(r))
|
||||||
|
return css
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const holder = document.getElementById('custom-styles-holder')
|
||||||
|
|
||||||
|
for (let i = holder.sheet.cssRules.length - 1; i >= 0; --i) {
|
||||||
|
holder.sheet.deleteRule(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
Object
|
||||||
|
.values(stylesheets)
|
||||||
|
.filter(x => x.ready)
|
||||||
|
.sort((a, b) => a.priority - b.priority)
|
||||||
|
.forEach(sheet => {
|
||||||
|
sheet.rules.forEach(r => holder.sheet.insertRule(r))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// Some older browsers do not support document.adoptedStyleSheets.
|
// Some older browsers do not support document.adoptedStyleSheets.
|
||||||
// In this case, we use the <style> elements.
|
// In this case, we use the <style> elements.
|
||||||
// Since the <style> elements we need are already in the DOM, there
|
// Since the <style> elements we need are already in the DOM, there
|
||||||
// is nothing to do here.
|
// is nothing to do here.
|
||||||
}
|
}, 500)
|
||||||
|
|
||||||
|
|
||||||
|
const EAGER_STYLE_ID = 'pleroma-eager-styles'
|
||||||
|
const LAZY_STYLE_ID = 'pleroma-lazy-styles'
|
||||||
|
|
||||||
export const generateTheme = (inputRuleset, callbacks, debug) => {
|
export const generateTheme = (inputRuleset, callbacks, debug) => {
|
||||||
const {
|
const {
|
||||||
|
|
@ -94,13 +123,17 @@ export const tryLoadCache = async () => {
|
||||||
if (!cache) return null
|
if (!cache) return null
|
||||||
try {
|
try {
|
||||||
if (cache.engineChecksum === getEngineChecksum()) {
|
if (cache.engineChecksum === getEngineChecksum()) {
|
||||||
const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
|
const eagerStyles = createStyleSheet(EAGER_STYLE_ID, 10)
|
||||||
const lazyStyles = createStyleSheet(LAZY_STYLE_ID)
|
const lazyStyles = createStyleSheet(LAZY_STYLE_ID, 20)
|
||||||
|
|
||||||
cache.data[0].forEach(rule => eagerStyles.sheet.insertRule(rule, 'index-max'))
|
cache.data[0].forEach(rule => eagerStyles.addRule(rule))
|
||||||
cache.data[1].forEach(rule => lazyStyles.sheet.insertRule(rule, 'index-max'))
|
cache.data[1].forEach(rule => lazyStyles.addRule(rule))
|
||||||
|
|
||||||
adoptStyleSheets([eagerStyles, lazyStyles])
|
eagerStyles.ready = true
|
||||||
|
lazyStyles.ready = true
|
||||||
|
|
||||||
|
// Don't do this, we need to wait until config adopts its styles first
|
||||||
|
//adoptStyleSheets()
|
||||||
|
|
||||||
console.info(`Loaded theme from cache`)
|
console.info(`Loaded theme from cache`)
|
||||||
return true
|
return true
|
||||||
|
|
@ -120,57 +153,29 @@ export const applyTheme = (
|
||||||
onFinish = () => {},
|
onFinish = () => {},
|
||||||
debug
|
debug
|
||||||
) => {
|
) => {
|
||||||
const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
|
const eagerStyles = createStyleSheet(EAGER_STYLE_ID, 10)
|
||||||
const lazyStyles = createStyleSheet(LAZY_STYLE_ID)
|
const lazyStyles = createStyleSheet(LAZY_STYLE_ID, 20)
|
||||||
|
|
||||||
const insertRule = (styles, rule) => {
|
|
||||||
try {
|
|
||||||
// Try to use modern syntax first
|
|
||||||
try {
|
|
||||||
styles.sheet.insertRule(rule, 'index-max')
|
|
||||||
styles.rules.push(rule)
|
|
||||||
} catch {
|
|
||||||
// Fallback for older browsers that don't support 'index-max'
|
|
||||||
styles.sheet.insertRule(rule, styles.sheet.cssRules.length)
|
|
||||||
styles.rules.push(rule)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Can\'t insert rule due to lack of support', e, rule)
|
|
||||||
|
|
||||||
// Try to sanitize the rule for better compatibility
|
|
||||||
try {
|
|
||||||
// Remove any potentially problematic CSS features
|
|
||||||
let sanitizedRule = rule
|
|
||||||
.replace(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter
|
|
||||||
.replace(/var\(--shadowFilter\)[^;]*;/g, '') // Remove shadowFilter references
|
|
||||||
|
|
||||||
if (sanitizedRule !== rule) {
|
|
||||||
styles.sheet.insertRule(sanitizedRule, styles.sheet.cssRules.length)
|
|
||||||
styles.rules.push(sanitizedRule)
|
|
||||||
}
|
|
||||||
} catch (e2) {
|
|
||||||
console.error('Failed to insert even sanitized rule', e2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { lazyProcessFunc } = generateTheme(
|
const { lazyProcessFunc } = generateTheme(
|
||||||
input,
|
input,
|
||||||
{
|
{
|
||||||
onNewRule (rule, isLazy) {
|
onNewRule (rule, isLazy) {
|
||||||
if (isLazy) {
|
if (isLazy) {
|
||||||
insertRule(lazyStyles, rule)
|
lazyStyles.addRule(rule)
|
||||||
} else {
|
} else {
|
||||||
insertRule(eagerStyles, rule)
|
eagerStyles.addRule(rule)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEagerFinished () {
|
onEagerFinished () {
|
||||||
adoptStyleSheets([eagerStyles])
|
eagerStyles.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
onEagerFinish()
|
onEagerFinish()
|
||||||
console.info('Eager part of theme finished, waiting for lazy part to finish to store cache')
|
console.info('Eager part of theme finished, waiting for lazy part to finish to store cache')
|
||||||
},
|
},
|
||||||
onLazyFinished () {
|
onLazyFinished () {
|
||||||
adoptStyleSheets([eagerStyles, lazyStyles])
|
lazyStyles.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] }
|
const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] }
|
||||||
onFinish(cache)
|
onFinish(cache)
|
||||||
localforage.setItem('pleromafe-theme-cache', cache)
|
localforage.setItem('pleromafe-theme-cache', cache)
|
||||||
|
|
@ -234,28 +239,23 @@ export const applyConfig = (input) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const head = document.head
|
|
||||||
|
|
||||||
const rules = Object
|
const rules = Object
|
||||||
.entries(config)
|
.entries(config)
|
||||||
.filter(([, v]) => v)
|
.filter(([, v]) => v)
|
||||||
.map(([k, v]) => `--${k}: ${v}`).join(';')
|
.map(([k, v]) => `--${k}: ${v}`).join(';')
|
||||||
|
|
||||||
document.getElementById('style-config')?.remove()
|
const styleSheet = createStyleSheet('theme-holder', 30)
|
||||||
const styleEl = document.createElement('style')
|
|
||||||
styleEl.id = 'style-config'
|
|
||||||
head.appendChild(styleEl)
|
|
||||||
const styleSheet = styleEl.sheet
|
|
||||||
|
|
||||||
styleSheet.toString()
|
styleSheet.addRule(`:root { ${rules} }`)
|
||||||
styleSheet.insertRule(`:root { ${rules} }`, 'index-max')
|
|
||||||
|
|
||||||
// TODO find a way to make this not apply to theme previews
|
// TODO find a way to make this not apply to theme previews
|
||||||
if (Object.prototype.hasOwnProperty.call(config, 'forcedRoundness')) {
|
if (Object.prototype.hasOwnProperty.call(config, 'forcedRoundness')) {
|
||||||
styleSheet.insertRule(` *:not(.preview-block) {
|
styleSheet.addRule(` *:not(.preview-block) {
|
||||||
--roundness: var(--forcedRoundness) !important;
|
--roundness: var(--forcedRoundness) !important;
|
||||||
}`, 'index-max')
|
}`)
|
||||||
}
|
}
|
||||||
|
styleSheet.ready = true
|
||||||
|
adoptStyleSheets()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getResourcesIndex = async (url, parser = JSON.parse) => {
|
export const getResourcesIndex = async (url, parser = JSON.parse) => {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ function isPushSupported () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrCreateServiceWorker () {
|
function getOrCreateServiceWorker () {
|
||||||
|
if (!isSWSupported()) return
|
||||||
const swType = process.env.HAS_MODULE_SERVICE_WORKER ? 'module' : 'classic'
|
const swType = process.env.HAS_MODULE_SERVICE_WORKER ? 'module' : 'classic'
|
||||||
return navigator.serviceWorker.register('/sw-pleroma.js', { type: swType })
|
return navigator.serviceWorker.register('/sw-pleroma.js', { type: swType })
|
||||||
.catch((err) => console.error('Unable to get or create a service worker.', err))
|
.catch((err) => console.error('Unable to get or create a service worker.', err))
|
||||||
|
|
@ -146,3 +147,11 @@ export function unregisterPushNotifications (token) {
|
||||||
]).catch((e) => console.warn(`Failed to disable Web Push Notifications: ${e.message}`))
|
]).catch((e) => console.warn(`Failed to disable Web Push Notifications: ${e.message}`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const shouldCache = process.env.NODE_ENV === 'production'
|
||||||
|
export const cacheKey = 'pleroma-fe'
|
||||||
|
export const emojiCacheKey = 'pleroma-fe-emoji'
|
||||||
|
|
||||||
|
export const clearCache = (key) => caches.delete(key)
|
||||||
|
|
||||||
|
export { getOrCreateServiceWorker }
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { convert, brightness } from 'chromatism'
|
import { convert, brightness } from 'chromatism'
|
||||||
import { alphaBlend, getTextColor, relativeLuminance } from '../color_convert/color_convert.js'
|
import { alphaBlend, arithmeticBlend, getTextColor, relativeLuminance } from '../color_convert/color_convert.js'
|
||||||
|
|
||||||
export const process = (text, functions, { findColor, findShadow }, { dynamicVars, staticVars }) => {
|
export const process = (text, functions, { findColor, findShadow }, { dynamicVars, staticVars }) => {
|
||||||
const { funcName, argsString } = /\$(?<funcName>\w+)\((?<argsString>[#a-zA-Z0-9-,.'"\s]*)\)/.exec(text).groups
|
const { funcName, argsString } = /\$(?<funcName>\w+)\((?<argsString>[#a-zA-Z0-9-+,.'"\s]*)\)/.exec(text).groups
|
||||||
const args = argsString.split(/ /g).map(a => a.trim())
|
const args = argsString.split(/ /g).map(a => a.trim())
|
||||||
|
|
||||||
const func = functions[funcName]
|
const func = functions[funcName]
|
||||||
|
|
@ -81,6 +81,23 @@ export const colorFunctions = {
|
||||||
return alphaBlend(background, amount, foreground)
|
return alphaBlend(background, amount, foreground)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
shift: {
|
||||||
|
argsNeeded: 2,
|
||||||
|
documentation: 'Arithmetic blend between two colors',
|
||||||
|
args: [
|
||||||
|
'origin: base color',
|
||||||
|
'value: shift value',
|
||||||
|
'operator: math operator to use (+ or -)'
|
||||||
|
],
|
||||||
|
exec: (args, { findColor }, { dynamicVars, staticVars }) => {
|
||||||
|
const [originArg, valueArg, operatorArg] = args
|
||||||
|
|
||||||
|
const origin = convert(findColor(originArg, { dynamicVars, staticVars })).rgb
|
||||||
|
const value = convert(findColor(valueArg, { dynamicVars, staticVars })).rgb
|
||||||
|
|
||||||
|
return arithmeticBlend(origin, value, operatorArg)
|
||||||
|
}
|
||||||
|
},
|
||||||
boost: {
|
boost: {
|
||||||
argsNeeded: 2,
|
argsNeeded: 2,
|
||||||
documentation: 'If given color is dark makes it darker, if color is light - makes it lighter',
|
documentation: 'If given color is dark makes it darker, if color is light - makes it lighter',
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const fetchAndUpdate = ({
|
||||||
args.bookmarkFolderId = bookmarkFolderId
|
args.bookmarkFolderId = bookmarkFolderId
|
||||||
args.tag = tag
|
args.tag = tag
|
||||||
args.withMuted = !hideMutedPosts
|
args.withMuted = !hideMutedPosts
|
||||||
if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
|
if (loggedIn && ['friends', 'public', 'publicAndExternal', 'bubble'].includes(timeline)) {
|
||||||
args.replyVisibility = replyVisibility
|
args.replyVisibility = replyVisibility
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,6 +63,10 @@ const fetchAndUpdate = ({
|
||||||
return apiService.fetchTimeline(args)
|
return apiService.fetchTimeline(args)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.errors) {
|
if (response.errors) {
|
||||||
|
if (timeline === 'favorites') {
|
||||||
|
rootState.instance.pleromaPublicFavouritesAvailable = false
|
||||||
|
return
|
||||||
|
}
|
||||||
throw new Error(`${response.status} ${response.statusText}`)
|
throw new Error(`${response.status} ${response.statusText}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
69
src/stores/auth_flow.js
Normal file
69
src/stores/auth_flow.js
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
const PASSWORD_STRATEGY = 'password'
|
||||||
|
const TOKEN_STRATEGY = 'token'
|
||||||
|
|
||||||
|
// MFA strategies
|
||||||
|
const TOTP_STRATEGY = 'totp'
|
||||||
|
const RECOVERY_STRATEGY = 'recovery'
|
||||||
|
|
||||||
|
export const useAuthFlowStore = defineStore('authFlow', {
|
||||||
|
// initial state
|
||||||
|
state: () => ({
|
||||||
|
settings: {},
|
||||||
|
strategy: PASSWORD_STRATEGY,
|
||||||
|
initStrategy: PASSWORD_STRATEGY // default strategy from config
|
||||||
|
}),
|
||||||
|
// getters
|
||||||
|
getters: {
|
||||||
|
requiredPassword: (state) => {
|
||||||
|
return state.strategy === PASSWORD_STRATEGY
|
||||||
|
},
|
||||||
|
requiredToken: (state) => {
|
||||||
|
return state.strategy === TOKEN_STRATEGY
|
||||||
|
},
|
||||||
|
requiredTOTP: (state) => {
|
||||||
|
return state.strategy === TOTP_STRATEGY
|
||||||
|
},
|
||||||
|
requiredRecovery: (state) => {
|
||||||
|
return state.strategy === RECOVERY_STRATEGY
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setInitialStrategy (strategy) {
|
||||||
|
if (strategy) {
|
||||||
|
this.initStrategy = strategy
|
||||||
|
this.strategy = strategy
|
||||||
|
}
|
||||||
|
},
|
||||||
|
requirePassword () {
|
||||||
|
this.strategy = PASSWORD_STRATEGY
|
||||||
|
},
|
||||||
|
requireToken () {
|
||||||
|
this.strategy = TOKEN_STRATEGY
|
||||||
|
},
|
||||||
|
requireMFA ({ settings }) {
|
||||||
|
this.settings = settings
|
||||||
|
this.strategy = TOTP_STRATEGY // default strategy of MFA
|
||||||
|
},
|
||||||
|
requireRecovery () {
|
||||||
|
this.strategy = RECOVERY_STRATEGY
|
||||||
|
},
|
||||||
|
requireTOTP () {
|
||||||
|
this.strategy = TOTP_STRATEGY
|
||||||
|
},
|
||||||
|
abortMFA () {
|
||||||
|
this.resetState()
|
||||||
|
},
|
||||||
|
resetState () {
|
||||||
|
this.strategy = this.initStrategy
|
||||||
|
this.settings = {}
|
||||||
|
},
|
||||||
|
async login ({ access_token: accessToken }) {
|
||||||
|
useOAuthStore().setToken(accessToken)
|
||||||
|
await window.vuex.dispatch('loginUser', accessToken, { root: true })
|
||||||
|
this.resetState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
109
src/sw.js
109
src/sw.js
|
|
@ -1,8 +1,10 @@
|
||||||
/* eslint-env serviceworker */
|
/* eslint-env serviceworker */
|
||||||
|
|
||||||
|
import 'virtual:pleroma-fe/service_worker_env'
|
||||||
import { storage } from 'src/lib/storage.js'
|
import { storage } from 'src/lib/storage.js'
|
||||||
import { parseNotification } from './services/entity_normalizer/entity_normalizer.service.js'
|
import { parseNotification } from './services/entity_normalizer/entity_normalizer.service.js'
|
||||||
import { prepareNotificationObject } from './services/notification_utils/notification_utils.js'
|
import { prepareNotificationObject } from './services/notification_utils/notification_utils.js'
|
||||||
|
import { shouldCache, cacheKey, emojiCacheKey } from './services/sw/sw.js'
|
||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
// Collects all messages for service workers
|
// Collects all messages for service workers
|
||||||
// Needed because service workers cannot use dynamic imports
|
// Needed because service workers cannot use dynamic imports
|
||||||
|
|
@ -85,6 +87,80 @@ const showPushNotification = async (event) => {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cacheFiles = self.serviceWorkerOption.assets
|
||||||
|
const isEmoji = req => {
|
||||||
|
if (req.method !== 'GET') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const url = new URL(req.url)
|
||||||
|
|
||||||
|
return url.pathname.startsWith('/emoji/')
|
||||||
|
}
|
||||||
|
const isNotMedia = req => {
|
||||||
|
if (req.method !== 'GET') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const url = new URL(req.url)
|
||||||
|
return !url.pathname.startsWith('/media/')
|
||||||
|
}
|
||||||
|
const isAsset = req => {
|
||||||
|
const url = new URL(req.url)
|
||||||
|
return cacheFiles.includes(url.pathname)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSuccessful = (resp) => {
|
||||||
|
if (!resp.ok) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if ((new URL(resp.url)).pathname === '/index.html') {
|
||||||
|
// For index.html itself, there is no fallback possible.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const type = resp.headers.get('Content-Type')
|
||||||
|
// Backend will revert to index.html if the file does not exist, so text/html for emojis and assets is a failure
|
||||||
|
return type && !type.includes('text/html')
|
||||||
|
}
|
||||||
|
|
||||||
|
self.addEventListener('install', async (event) => {
|
||||||
|
if (shouldCache) {
|
||||||
|
event.waitUntil((async () => {
|
||||||
|
// Do not preload i18n and emoji annotations to speed up loading
|
||||||
|
const shouldPreload = (route) => {
|
||||||
|
return !route.startsWith('/static/js/i18n/') && !route.startsWith('/static/js/emoji-annotations/')
|
||||||
|
}
|
||||||
|
const cache = await caches.open(cacheKey)
|
||||||
|
await Promise.allSettled(cacheFiles.filter(shouldPreload).map(async (route) => {
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Cache/add
|
||||||
|
// originally we used addAll() but it will raise a problem in one edge case:
|
||||||
|
// when the file for the route is not found, backend will return index.html with code 200
|
||||||
|
// but it's wrong, and it's cached, so we end up with a bad cache.
|
||||||
|
// this can happen when you refresh when you are in the process of upgrading
|
||||||
|
// the frontend.
|
||||||
|
const resp = await fetch(route)
|
||||||
|
if (isSuccessful(resp)) {
|
||||||
|
await cache.put(route, resp)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('activate', async (event) => {
|
||||||
|
if (shouldCache) {
|
||||||
|
event.waitUntil((async () => {
|
||||||
|
const cache = await caches.open(cacheKey)
|
||||||
|
const keys = await cache.keys()
|
||||||
|
await Promise.all(
|
||||||
|
keys.filter(request => {
|
||||||
|
const url = new URL(request.url)
|
||||||
|
const shouldKeep = cacheFiles.includes(url.pathname)
|
||||||
|
return !shouldKeep
|
||||||
|
}).map(k => cache.delete(k))
|
||||||
|
)
|
||||||
|
})())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
self.addEventListener('push', async (event) => {
|
self.addEventListener('push', async (event) => {
|
||||||
if (event.data) {
|
if (event.data) {
|
||||||
// Supposedly, we HAVE to return a promise inside waitUntil otherwise it will
|
// Supposedly, we HAVE to return a promise inside waitUntil otherwise it will
|
||||||
|
|
@ -143,4 +219,35 @@ self.addEventListener('notificationclick', (event) => {
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('sw here')
|
self.addEventListener('fetch', (event) => {
|
||||||
|
// Do not mess up with remote things
|
||||||
|
const isSameOrigin = (new URL(event.request.url)).origin === self.location.origin
|
||||||
|
if (shouldCache && event.request.method === 'GET' && isSameOrigin && isNotMedia(event.request)) {
|
||||||
|
// this is a bit spammy
|
||||||
|
// console.debug('[Service worker] fetch:', event.request.url)
|
||||||
|
event.respondWith((async () => {
|
||||||
|
const r = await caches.match(event.request)
|
||||||
|
const isEmojiReq = isEmoji(event.request)
|
||||||
|
|
||||||
|
if (r && isSuccessful(r)) {
|
||||||
|
console.debug('[Service worker] already cached:', event.request.url)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(event.request)
|
||||||
|
if (response.ok &&
|
||||||
|
isSuccessful(response) &&
|
||||||
|
(isEmojiReq || isAsset(event.request))) {
|
||||||
|
console.debug(`[Service worker] caching ${isEmojiReq ? 'emoji' : 'asset'}:`, event.request.url)
|
||||||
|
const cache = await caches.open(isEmojiReq ? emojiCacheKey : cacheKey)
|
||||||
|
await cache.put(event.request.clone(), response.clone())
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[Service worker] error when caching emoji:', e)
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
})())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,14 @@ export default defineConfig(async ({ mode, command }) => {
|
||||||
return 'static/js/[name].[hash].js'
|
return 'static/js/[name].[hash].js'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chunkFileNames () {
|
chunkFileNames (chunkInfo) {
|
||||||
|
if (chunkInfo.facadeModuleId) {
|
||||||
|
if (chunkInfo.facadeModuleId.includes('node_modules/@kazvmoe-infra/unicode-emoji-json/annotations/')) {
|
||||||
|
return 'static/js/emoji-annotations/[name].[hash].js'
|
||||||
|
} else if (chunkInfo.facadeModuleId.includes('src/i18n/')) {
|
||||||
|
return 'static/js/i18n/[name].[hash].js'
|
||||||
|
}
|
||||||
|
}
|
||||||
return 'static/js/[name].[hash].js'
|
return 'static/js/[name].[hash].js'
|
||||||
},
|
},
|
||||||
assetFileNames (assetInfo) {
|
assetFileNames (assetInfo) {
|
||||||
|
|
|
||||||
334
yarn.lock
334
yarn.lock
|
|
@ -411,6 +411,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.27.1"
|
"@babel/types" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/parser@^7.27.5":
|
||||||
|
version "7.27.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.5.tgz#ed22f871f110aa285a6fd934a0efed621d118826"
|
||||||
|
integrity sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.27.3"
|
||||||
|
|
||||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1":
|
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1":
|
||||||
version "7.27.1"
|
version "7.27.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9"
|
||||||
|
|
@ -1061,6 +1068,14 @@
|
||||||
"@babel/helper-string-parser" "^7.27.1"
|
"@babel/helper-string-parser" "^7.27.1"
|
||||||
"@babel/helper-validator-identifier" "^7.27.1"
|
"@babel/helper-validator-identifier" "^7.27.1"
|
||||||
|
|
||||||
|
"@babel/types@^7.27.3":
|
||||||
|
version "7.27.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.6.tgz#a434ca7add514d4e646c80f7375c0aa2befc5535"
|
||||||
|
integrity sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-string-parser" "^7.27.1"
|
||||||
|
"@babel/helper-validator-identifier" "^7.27.1"
|
||||||
|
|
||||||
"@bazel/runfiles@^6.3.1":
|
"@bazel/runfiles@^6.3.1":
|
||||||
version "6.3.1"
|
version "6.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-6.3.1.tgz#3f8824b2d82853377799d42354b4df78ab0ace0b"
|
resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-6.3.1.tgz#3f8824b2d82853377799d42354b4df78ab0ace0b"
|
||||||
|
|
@ -1587,10 +1602,10 @@
|
||||||
"@jridgewell/resolve-uri" "^3.1.0"
|
"@jridgewell/resolve-uri" "^3.1.0"
|
||||||
"@jridgewell/sourcemap-codec" "^1.4.14"
|
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||||
|
|
||||||
"@kazvmoe-infra/pinch-zoom-element@1.2.0":
|
"@kazvmoe-infra/pinch-zoom-element@1.3.0":
|
||||||
version "1.2.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@kazvmoe-infra/pinch-zoom-element/-/pinch-zoom-element-1.2.0.tgz#eb3ca34c53b4410c689d60aca02f4a497ce84aba"
|
resolved "https://registry.yarnpkg.com/@kazvmoe-infra/pinch-zoom-element/-/pinch-zoom-element-1.3.0.tgz#a5e35ab190f93d016b8a83f69004fc69a8e6b774"
|
||||||
integrity sha512-HBrhH5O/Fsp2bB7EGTXzCsBAVcMjknSagKC5pBdGpKsF8meHISR0kjDIdw4YoE0S+0oNMwJ6ZUZyIBrdywxPPw==
|
integrity sha512-YIx1ZsCLyFB/xhJVMc81yLNJO/ZYveYGws0033ZPPyrFLgLwrQrkx79lC1xBIcWlWnvPioTVdmOpnBeTv/0zNw==
|
||||||
dependencies:
|
dependencies:
|
||||||
pointer-tracker "^2.0.3"
|
pointer-tracker "^2.0.3"
|
||||||
|
|
||||||
|
|
@ -1622,10 +1637,10 @@
|
||||||
zod "^3.23.8"
|
zod "^3.23.8"
|
||||||
zod-to-json-schema "^3.24.1"
|
zod-to-json-schema "^3.24.1"
|
||||||
|
|
||||||
"@mswjs/interceptors@^0.37.0":
|
"@mswjs/interceptors@^0.39.1":
|
||||||
version "0.37.6"
|
version "0.39.2"
|
||||||
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.37.6.tgz#2635319b7a81934e1ef1b5593ef7910347e2b761"
|
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.39.2.tgz#de9de0ab23f99d387c7904df7219a92157d1d666"
|
||||||
integrity sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==
|
integrity sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@open-draft/deferred-promise" "^2.2.0"
|
"@open-draft/deferred-promise" "^2.2.0"
|
||||||
"@open-draft/logger" "^0.3.0"
|
"@open-draft/logger" "^0.3.0"
|
||||||
|
|
@ -2309,6 +2324,17 @@
|
||||||
estree-walker "^2.0.2"
|
estree-walker "^2.0.2"
|
||||||
source-map-js "^1.2.0"
|
source-map-js "^1.2.0"
|
||||||
|
|
||||||
|
"@vue/compiler-core@3.5.17":
|
||||||
|
version "3.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.17.tgz#23d291bd01b863da3ef2e26e7db84d8e01a9b4c5"
|
||||||
|
integrity sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.27.5"
|
||||||
|
"@vue/shared" "3.5.17"
|
||||||
|
entities "^4.5.0"
|
||||||
|
estree-walker "^2.0.2"
|
||||||
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
"@vue/compiler-dom@3.5.13":
|
"@vue/compiler-dom@3.5.13":
|
||||||
version "3.5.13"
|
version "3.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58"
|
||||||
|
|
@ -2317,7 +2343,30 @@
|
||||||
"@vue/compiler-core" "3.5.13"
|
"@vue/compiler-core" "3.5.13"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.13"
|
||||||
|
|
||||||
"@vue/compiler-sfc@3.5.13", "@vue/compiler-sfc@^3.5.13":
|
"@vue/compiler-dom@3.5.17":
|
||||||
|
version "3.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz#7bc19a20e23b670243a64b47ce3a890239b870be"
|
||||||
|
integrity sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-core" "3.5.17"
|
||||||
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
|
"@vue/compiler-sfc@3.5.17":
|
||||||
|
version "3.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.17.tgz#c518871276e26593612bdab36f3f5bcd053b13bf"
|
||||||
|
integrity sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser" "^7.27.5"
|
||||||
|
"@vue/compiler-core" "3.5.17"
|
||||||
|
"@vue/compiler-dom" "3.5.17"
|
||||||
|
"@vue/compiler-ssr" "3.5.17"
|
||||||
|
"@vue/shared" "3.5.17"
|
||||||
|
estree-walker "^2.0.2"
|
||||||
|
magic-string "^0.30.17"
|
||||||
|
postcss "^8.5.6"
|
||||||
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
|
"@vue/compiler-sfc@^3.5.13":
|
||||||
version "3.5.13"
|
version "3.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz#461f8bd343b5c06fac4189c4fef8af32dea82b46"
|
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz#461f8bd343b5c06fac4189c4fef8af32dea82b46"
|
||||||
integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==
|
integrity sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==
|
||||||
|
|
@ -2340,6 +2389,14 @@
|
||||||
"@vue/compiler-dom" "3.5.13"
|
"@vue/compiler-dom" "3.5.13"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.13"
|
||||||
|
|
||||||
|
"@vue/compiler-ssr@3.5.17":
|
||||||
|
version "3.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz#14ba3b7bba6e0e1fd02002316263165a5d1046c7"
|
||||||
|
integrity sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==
|
||||||
|
dependencies:
|
||||||
|
"@vue/compiler-dom" "3.5.17"
|
||||||
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.6.4":
|
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.6.4":
|
||||||
version "6.6.4"
|
version "6.6.4"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
|
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
|
||||||
|
|
@ -2372,44 +2429,49 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
rfdc "^1.4.1"
|
rfdc "^1.4.1"
|
||||||
|
|
||||||
"@vue/reactivity@3.5.13":
|
"@vue/reactivity@3.5.17":
|
||||||
version "3.5.13"
|
version "3.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.13.tgz#b41ff2bb865e093899a22219f5b25f97b6fe155f"
|
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.17.tgz#169b5dcf96c7f23788e5ed9745ec8a7227f2125e"
|
||||||
integrity sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==
|
integrity sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
"@vue/runtime-core@3.5.13":
|
"@vue/runtime-core@3.5.17":
|
||||||
version "3.5.13"
|
version "3.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz#1fafa4bf0b97af0ebdd9dbfe98cd630da363a455"
|
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.17.tgz#b17bd41e13011e85e9b1025545292d43f5512730"
|
||||||
integrity sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==
|
integrity sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/reactivity" "3.5.13"
|
"@vue/reactivity" "3.5.17"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
"@vue/runtime-dom@3.5.13":
|
"@vue/runtime-dom@3.5.17":
|
||||||
version "3.5.13"
|
version "3.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz#610fc795de9246300e8ae8865930d534e1246215"
|
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.17.tgz#8e325e29cd03097fe179032fc8df384a426fc83a"
|
||||||
integrity sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==
|
integrity sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/reactivity" "3.5.13"
|
"@vue/reactivity" "3.5.17"
|
||||||
"@vue/runtime-core" "3.5.13"
|
"@vue/runtime-core" "3.5.17"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.17"
|
||||||
csstype "^3.1.3"
|
csstype "^3.1.3"
|
||||||
|
|
||||||
"@vue/server-renderer@3.5.13":
|
"@vue/server-renderer@3.5.17":
|
||||||
version "3.5.13"
|
version "3.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz#429ead62ee51de789646c22efe908e489aad46f7"
|
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.17.tgz#9b8fd6a40a3d55322509fafe78ac841ede649fbe"
|
||||||
integrity sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==
|
integrity sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-ssr" "3.5.13"
|
"@vue/compiler-ssr" "3.5.17"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
"@vue/shared@3.5.13", "@vue/shared@^3.5.13":
|
"@vue/shared@3.5.13", "@vue/shared@^3.5.13":
|
||||||
version "3.5.13"
|
version "3.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f"
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f"
|
||||||
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
|
integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
|
||||||
|
|
||||||
|
"@vue/shared@3.5.17":
|
||||||
|
version "3.5.17"
|
||||||
|
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.17.tgz#e8b3a41f0be76499882a89e8ed40d86a70fa4b70"
|
||||||
|
integrity sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==
|
||||||
|
|
||||||
"@vue/test-utils@2.4.6":
|
"@vue/test-utils@2.4.6":
|
||||||
version "2.4.6"
|
version "2.4.6"
|
||||||
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.4.6.tgz#7d534e70c4319d2a587d6a3b45a39e9695ade03c"
|
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.4.6.tgz#7d534e70c4319d2a587d6a3b45a39e9695ade03c"
|
||||||
|
|
@ -3348,17 +3410,6 @@ cross-spawn@7.0.6, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
|
||||||
shebang-command "^2.0.0"
|
shebang-command "^2.0.0"
|
||||||
which "^2.0.1"
|
which "^2.0.1"
|
||||||
|
|
||||||
cross-spawn@^6.0.0:
|
|
||||||
version "6.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57"
|
|
||||||
integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==
|
|
||||||
dependencies:
|
|
||||||
nice-try "^1.0.4"
|
|
||||||
path-key "^2.0.1"
|
|
||||||
semver "^5.5.0"
|
|
||||||
shebang-command "^1.2.0"
|
|
||||||
which "^1.2.9"
|
|
||||||
|
|
||||||
css-functions-list@^3.2.3:
|
css-functions-list@^3.2.3:
|
||||||
version "3.2.3"
|
version "3.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.3.tgz#95652b0c24f0f59b291a9fc386041a19d4f40dbe"
|
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.3.tgz#95652b0c24f0f59b291a9fc386041a19d4f40dbe"
|
||||||
|
|
@ -4199,18 +4250,20 @@ eventsource@^3.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
eventsource-parser "^3.0.1"
|
eventsource-parser "^3.0.1"
|
||||||
|
|
||||||
execa@^1.0.0:
|
execa@^5.1.1:
|
||||||
version "1.0.0"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
|
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||||
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
|
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn "^6.0.0"
|
cross-spawn "^7.0.3"
|
||||||
get-stream "^4.0.0"
|
get-stream "^6.0.0"
|
||||||
is-stream "^1.1.0"
|
human-signals "^2.1.0"
|
||||||
npm-run-path "^2.0.0"
|
is-stream "^2.0.0"
|
||||||
p-finally "^1.0.0"
|
merge-stream "^2.0.0"
|
||||||
signal-exit "^3.0.0"
|
npm-run-path "^4.0.1"
|
||||||
strip-eof "^1.0.0"
|
onetime "^5.1.2"
|
||||||
|
signal-exit "^3.0.3"
|
||||||
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
expect-type@^1.2.1:
|
expect-type@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
|
|
@ -4556,13 +4609,6 @@ get-proto@^1.0.0, get-proto@^1.0.1:
|
||||||
dunder-proto "^1.0.1"
|
dunder-proto "^1.0.1"
|
||||||
es-object-atoms "^1.0.0"
|
es-object-atoms "^1.0.0"
|
||||||
|
|
||||||
get-stream@^4.0.0:
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
|
|
||||||
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
|
|
||||||
dependencies:
|
|
||||||
pump "^3.0.0"
|
|
||||||
|
|
||||||
get-stream@^5.1.0:
|
get-stream@^5.1.0:
|
||||||
version "5.2.0"
|
version "5.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||||
|
|
@ -4570,6 +4616,11 @@ get-stream@^5.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
pump "^3.0.0"
|
pump "^3.0.0"
|
||||||
|
|
||||||
|
get-stream@^6.0.0:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||||
|
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
||||||
|
|
||||||
get-symbol-description@^1.1.0:
|
get-symbol-description@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee"
|
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee"
|
||||||
|
|
@ -4868,6 +4919,11 @@ https-proxy-agent@^7.0.5, https-proxy-agent@^7.0.6:
|
||||||
agent-base "^7.1.2"
|
agent-base "^7.1.2"
|
||||||
debug "4"
|
debug "4"
|
||||||
|
|
||||||
|
human-signals@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
|
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||||
|
|
||||||
iconv-lite@0.6.3, iconv-lite@^0.6.3:
|
iconv-lite@0.6.3, iconv-lite@^0.6.3:
|
||||||
version "0.6.3"
|
version "0.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
||||||
|
|
@ -4940,11 +4996,6 @@ internal-slot@^1.1.0:
|
||||||
hasown "^2.0.2"
|
hasown "^2.0.2"
|
||||||
side-channel "^1.1.0"
|
side-channel "^1.1.0"
|
||||||
|
|
||||||
interpret@^1.0.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
|
|
||||||
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
|
|
||||||
|
|
||||||
ip-address@^9.0.5:
|
ip-address@^9.0.5:
|
||||||
version "9.0.5"
|
version "9.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
|
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
|
||||||
|
|
@ -5163,10 +5214,10 @@ is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bound "^1.0.3"
|
call-bound "^1.0.3"
|
||||||
|
|
||||||
is-stream@^1.1.0:
|
is-stream@^2.0.0:
|
||||||
version "1.1.0"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
|
||||||
integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
|
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
|
||||||
|
|
||||||
is-string@^1.0.7, is-string@^1.1.1:
|
is-string@^1.0.7, is-string@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
|
|
@ -5650,6 +5701,11 @@ merge-descriptors@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808"
|
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808"
|
||||||
integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==
|
integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==
|
||||||
|
|
||||||
|
merge-stream@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||||
|
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||||
|
|
||||||
merge2@^1.3.0, merge2@^1.4.1:
|
merge2@^1.3.0, merge2@^1.4.1:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
|
|
@ -5793,16 +5849,16 @@ ms@2.1.3, ms@^2.1.1, ms@^2.1.3:
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
msw@2.7.6:
|
msw@2.10.2:
|
||||||
version "2.7.6"
|
version "2.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/msw/-/msw-2.7.6.tgz#1471ce4311f4c173f287dced31dee211b6958deb"
|
resolved "https://registry.yarnpkg.com/msw/-/msw-2.10.2.tgz#e7a56ed0b6865b00a30b4c4a5b59e5388fd48315"
|
||||||
integrity sha512-P+rwn43ktxN8ghcl8q+hSAUlEi0PbJpDhGmDkw4zeUnRj3hBCVynWD+dTu38yLYKCE9ZF1OYcvpy7CTBRcqkZA==
|
integrity sha512-RCKM6IZseZQCWcSWlutdf590M8nVfRHG1ImwzOtwz8IYxgT4zhUO0rfTcTvDGiaFE0Rhcc+h43lcF3Jc9gFtwQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bundled-es-modules/cookie" "^2.0.1"
|
"@bundled-es-modules/cookie" "^2.0.1"
|
||||||
"@bundled-es-modules/statuses" "^1.0.1"
|
"@bundled-es-modules/statuses" "^1.0.1"
|
||||||
"@bundled-es-modules/tough-cookie" "^0.1.6"
|
"@bundled-es-modules/tough-cookie" "^0.1.6"
|
||||||
"@inquirer/confirm" "^5.0.0"
|
"@inquirer/confirm" "^5.0.0"
|
||||||
"@mswjs/interceptors" "^0.37.0"
|
"@mswjs/interceptors" "^0.39.1"
|
||||||
"@open-draft/deferred-promise" "^2.2.0"
|
"@open-draft/deferred-promise" "^2.2.0"
|
||||||
"@open-draft/until" "^2.1.0"
|
"@open-draft/until" "^2.1.0"
|
||||||
"@types/cookie" "^0.6.0"
|
"@types/cookie" "^0.6.0"
|
||||||
|
|
@ -5822,7 +5878,7 @@ mute-stream@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
|
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
|
||||||
integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==
|
integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==
|
||||||
|
|
||||||
nanoid@^3.3.8:
|
nanoid@^3.3.11, nanoid@^3.3.8:
|
||||||
version "3.3.11"
|
version "3.3.11"
|
||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
|
||||||
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
|
||||||
|
|
@ -5842,11 +5898,6 @@ netmask@^2.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
|
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
|
||||||
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
|
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
|
||||||
|
|
||||||
nice-try@^1.0.4:
|
|
||||||
version "1.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
|
||||||
|
|
||||||
nightwatch-axe-verbose@^2.3.0:
|
nightwatch-axe-verbose@^2.3.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.3.1.tgz#42cd226989cb5205b699db42d74b1b967587d099"
|
resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.3.1.tgz#42cd226989cb5205b699db42d74b1b967587d099"
|
||||||
|
|
@ -5921,12 +5972,12 @@ normalize-range@^0.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||||
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
|
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
|
||||||
|
|
||||||
npm-run-path@^2.0.0:
|
npm-run-path@^4.0.1:
|
||||||
version "2.0.2"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
|
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||||
integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
|
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key "^2.0.0"
|
path-key "^3.0.0"
|
||||||
|
|
||||||
nth-check@^2.1.1:
|
nth-check@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
|
|
@ -6018,7 +6069,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
onetime@^5.1.0:
|
onetime@^5.1.0, onetime@^5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
||||||
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
|
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
|
||||||
|
|
@ -6075,11 +6126,6 @@ own-keys@^1.0.1:
|
||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
safe-push-apply "^1.0.0"
|
safe-push-apply "^1.0.0"
|
||||||
|
|
||||||
p-finally@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
|
||||||
integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
|
|
||||||
|
|
||||||
p-limit@^2.0.0, p-limit@^2.2.0:
|
p-limit@^2.0.0, p-limit@^2.2.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||||
|
|
@ -6203,12 +6249,7 @@ path-is-absolute@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
|
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
|
||||||
|
|
||||||
path-key@^2.0.0, path-key@^2.0.1:
|
path-key@^3.0.0, path-key@^3.1.0:
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
|
||||||
integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
|
|
||||||
|
|
||||||
path-key@^3.1.0:
|
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
|
|
@ -6416,6 +6457,15 @@ postcss@8.5.3, postcss@^8.4.48, postcss@^8.5.0, postcss@^8.5.3:
|
||||||
picocolors "^1.1.1"
|
picocolors "^1.1.1"
|
||||||
source-map-js "^1.2.1"
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
|
postcss@^8.5.6:
|
||||||
|
version "8.5.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
|
||||||
|
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
|
||||||
|
dependencies:
|
||||||
|
nanoid "^3.3.11"
|
||||||
|
picocolors "^1.1.1"
|
||||||
|
source-map-js "^1.2.1"
|
||||||
|
|
||||||
prelude-ls@^1.2.1:
|
prelude-ls@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||||
|
|
@ -6596,13 +6646,6 @@ readdirp@~3.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
picomatch "^2.2.1"
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
rechoir@^0.6.2:
|
|
||||||
version "0.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
|
|
||||||
integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==
|
|
||||||
dependencies:
|
|
||||||
resolve "^1.1.6"
|
|
||||||
|
|
||||||
reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
|
reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9"
|
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9"
|
||||||
|
|
@ -6705,7 +6748,7 @@ resolve-pkg-maps@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
|
resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
|
||||||
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
||||||
|
|
||||||
resolve@^1.1.6, resolve@^1.14.2, resolve@^1.22.4:
|
resolve@^1.14.2, resolve@^1.22.4:
|
||||||
version "1.22.10"
|
version "1.22.10"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
|
||||||
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
|
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
|
||||||
|
|
@ -6832,10 +6875,10 @@ safe-regex-test@^1.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
sass@1.87.0:
|
sass@1.89.2:
|
||||||
version "1.87.0"
|
version "1.89.2"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.87.0.tgz#8cceb36fa63fb48a8d5d7f2f4c13b49c524b723e"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.89.2.tgz#a771716aeae774e2b529f72c0ff2dfd46c9de10e"
|
||||||
integrity sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==
|
integrity sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar "^4.0.0"
|
chokidar "^4.0.0"
|
||||||
immutable "^5.0.2"
|
immutable "^5.0.2"
|
||||||
|
|
@ -6872,12 +6915,12 @@ semver@7.5.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache "^6.0.0"
|
lru-cache "^6.0.0"
|
||||||
|
|
||||||
semver@7.7.1, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
|
semver@7.7.2:
|
||||||
version "7.7.1"
|
version "7.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
|
||||||
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
|
||||||
|
|
||||||
semver@^5.5.0, semver@^5.6.0:
|
semver@^5.6.0:
|
||||||
version "5.7.2"
|
version "5.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
|
||||||
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
|
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
|
||||||
|
|
@ -6887,6 +6930,11 @@ semver@^6.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
|
||||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
|
semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
|
||||||
|
version "7.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
||||||
|
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
||||||
|
|
||||||
send@^1.1.0, send@^1.2.0:
|
send@^1.1.0, send@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/send/-/send-1.2.0.tgz#32a7554fb777b831dfa828370f773a3808d37212"
|
resolved "https://registry.yarnpkg.com/send/-/send-1.2.0.tgz#32a7554fb777b831dfa828370f773a3808d37212"
|
||||||
|
|
@ -6974,13 +7022,6 @@ shallow-clone@^3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
kind-of "^6.0.2"
|
kind-of "^6.0.2"
|
||||||
|
|
||||||
shebang-command@^1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
|
||||||
integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
|
|
||||||
dependencies:
|
|
||||||
shebang-regex "^1.0.0"
|
|
||||||
|
|
||||||
shebang-command@^2.0.0:
|
shebang-command@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||||
|
|
@ -6988,25 +7029,18 @@ shebang-command@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shebang-regex "^3.0.0"
|
shebang-regex "^3.0.0"
|
||||||
|
|
||||||
shebang-regex@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
|
||||||
integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
|
|
||||||
|
|
||||||
shebang-regex@^3.0.0:
|
shebang-regex@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||||
|
|
||||||
shelljs@0.9.2:
|
shelljs@0.10.0:
|
||||||
version "0.9.2"
|
version "0.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.9.2.tgz#a8ac724434520cd7ae24d52071e37a18ac2bb183"
|
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.10.0.tgz#e3bbae99b0f3f0cc5dce05b46a346fae2090e883"
|
||||||
integrity sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==
|
integrity sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==
|
||||||
dependencies:
|
dependencies:
|
||||||
execa "^1.0.0"
|
execa "^5.1.1"
|
||||||
fast-glob "^3.3.2"
|
fast-glob "^3.3.2"
|
||||||
interpret "^1.0.0"
|
|
||||||
rechoir "^0.6.2"
|
|
||||||
|
|
||||||
side-channel-list@^1.0.0:
|
side-channel-list@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
|
|
@ -7053,7 +7087,7 @@ siginfo@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
|
resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
|
||||||
integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==
|
integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==
|
||||||
|
|
||||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||||
version "3.0.7"
|
version "3.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||||
|
|
@ -7293,10 +7327,10 @@ strip-bom@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||||
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
||||||
|
|
||||||
strip-eof@^1.0.0:
|
strip-final-newline@^2.0.0:
|
||||||
version "1.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
strip-json-comments@3.1.1, strip-json-comments@^3.1.1:
|
strip-json-comments@3.1.1, strip-json-comments@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
|
|
@ -7910,16 +7944,16 @@ vue-virtual-scroller@^2.0.0-beta.7:
|
||||||
vue-observe-visibility "^2.0.0-alpha.1"
|
vue-observe-visibility "^2.0.0-alpha.1"
|
||||||
vue-resize "^2.0.0-alpha.1"
|
vue-resize "^2.0.0-alpha.1"
|
||||||
|
|
||||||
vue@3.5.13:
|
vue@3.5.17:
|
||||||
version "3.5.13"
|
version "3.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.13.tgz#9f760a1a982b09c0c04a867903fc339c9f29ec0a"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.17.tgz#ea8a6a45abb2b0620e7d479319ce8434b55650cf"
|
||||||
integrity sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==
|
integrity sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vue/compiler-dom" "3.5.13"
|
"@vue/compiler-dom" "3.5.17"
|
||||||
"@vue/compiler-sfc" "3.5.13"
|
"@vue/compiler-sfc" "3.5.17"
|
||||||
"@vue/runtime-dom" "3.5.13"
|
"@vue/runtime-dom" "3.5.17"
|
||||||
"@vue/server-renderer" "3.5.13"
|
"@vue/server-renderer" "3.5.17"
|
||||||
"@vue/shared" "3.5.13"
|
"@vue/shared" "3.5.17"
|
||||||
|
|
||||||
vuex@4.1.0:
|
vuex@4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
|
|
@ -8025,7 +8059,7 @@ which-typed-array@^1.1.13, which-typed-array@^1.1.16, which-typed-array@^1.1.18:
|
||||||
gopd "^1.2.0"
|
gopd "^1.2.0"
|
||||||
has-tostringtag "^1.0.2"
|
has-tostringtag "^1.0.2"
|
||||||
|
|
||||||
which@^1.2.9, which@^1.3.1:
|
which@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue