mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 04:23:09 +02:00
Merge branch 'develop'
This commit is contained in:
commit
e0fc8cbf8f
15 changed files with 75 additions and 16 deletions
|
@ -8,6 +8,15 @@
|
||||||
|
|
||||||
You should also include the user name that made the change.
|
You should also include the user name that made the change.
|
||||||
-->
|
-->
|
||||||
|
## 13.5.4 (2023/02/09)
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
- Server: UIのHTML(ノートなどの特別なページを除く)のキャッシュ時間を15秒から30秒に
|
||||||
|
- i/notificationsのレートリミットを緩和
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
- fix(client): validate url to improve security
|
||||||
|
- fix(client): dateの初期値が正常に入らない時がある
|
||||||
|
|
||||||
## 13.5.3 (2023/02/09)
|
## 13.5.3 (2023/02/09)
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ unblockConfirm: "¿Quiere dejar de bloquear esta cuenta?"
|
||||||
suspendConfirm: "¿Quiere suspender esta cuenta?"
|
suspendConfirm: "¿Quiere suspender esta cuenta?"
|
||||||
unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?"
|
unsuspendConfirm: "¿Quiere dejar de suspender esta cuenta?"
|
||||||
selectList: "Seleccione una lista"
|
selectList: "Seleccione una lista"
|
||||||
|
selectChannel: "Seleccionar canal"
|
||||||
selectAntenna: "Seleccionar antena"
|
selectAntenna: "Seleccionar antena"
|
||||||
selectWidget: "Seleccionar widget"
|
selectWidget: "Seleccionar widget"
|
||||||
editWidgets: "Editar widgets"
|
editWidgets: "Editar widgets"
|
||||||
|
|
|
@ -940,6 +940,8 @@ cannotPerformTemporaryDescription: "操作回数が制限を超過するため
|
||||||
preset: "プリセット"
|
preset: "プリセット"
|
||||||
selectFromPresets: "プリセットから選択"
|
selectFromPresets: "プリセットから選択"
|
||||||
achievements: "実績"
|
achievements: "実績"
|
||||||
|
gotInvalidResponseError: "サーバーの応答が無効です"
|
||||||
|
gotInvalidResponseErrorDescription: "サーバーがダウンまたはメンテナンスしている可能性があります。しばらくしてから再度お試しください。"
|
||||||
|
|
||||||
_achievements:
|
_achievements:
|
||||||
earnedAt: "獲得日時"
|
earnedAt: "獲得日時"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "13.5.3",
|
"version": "13.5.4",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -15,8 +15,8 @@ export const meta = {
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
|
|
||||||
limit: {
|
limit: {
|
||||||
duration: 60000,
|
duration: 30000,
|
||||||
max: 15,
|
max: 30,
|
||||||
},
|
},
|
||||||
|
|
||||||
kind: 'read:notifications',
|
kind: 'read:notifications',
|
||||||
|
|
|
@ -337,7 +337,7 @@ export class ClientServerService {
|
||||||
|
|
||||||
const renderBase = async (reply: FastifyReply) => {
|
const renderBase = async (reply: FastifyReply) => {
|
||||||
const meta = await this.metaService.fetch();
|
const meta = await this.metaService.fetch();
|
||||||
reply.header('Cache-Control', 'public, max-age=15');
|
reply.header('Cache-Control', 'public, max-age=30');
|
||||||
return await reply.view('base', {
|
return await reply.view('base', {
|
||||||
img: meta.bannerUrl,
|
img: meta.bannerUrl,
|
||||||
title: meta.name ?? 'Misskey',
|
title: meta.name ?? 'Misskey',
|
||||||
|
|
|
@ -35,7 +35,8 @@ html
|
||||||
link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
|
link(rel='prefetch' href='https://xn--931a.moe/assets/info.jpg')
|
||||||
link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
|
link(rel='prefetch' href='https://xn--931a.moe/assets/not-found.jpg')
|
||||||
link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
|
link(rel='prefetch' href='https://xn--931a.moe/assets/error.jpg')
|
||||||
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css')
|
//- https://github.com/misskey-dev/misskey/issues/9842
|
||||||
|
link(rel='stylesheet' href='/assets/tabler-icons/tabler-icons.min.css?v2.2.0')
|
||||||
link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
|
link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
|
||||||
|
|
||||||
if !config.clientManifestExists
|
if !config.clientManifestExists
|
||||||
|
|
|
@ -42,7 +42,7 @@ import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: string | number;
|
modelValue: string | number;
|
||||||
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search';
|
type?: 'text' | 'number' | 'password' | 'email' | 'url' | 'date' | 'time' | 'search' | 'datetime-local';
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
@ -35,6 +35,9 @@ export const apiWithDialog = ((
|
||||||
} else if (err.code.startsWith('TOO_MANY')) {
|
} else if (err.code.startsWith('TOO_MANY')) {
|
||||||
title = i18n.ts.youCannotCreateAnymore;
|
title = i18n.ts.youCannotCreateAnymore;
|
||||||
text = `${i18n.ts.error}: ${err.id}`;
|
text = `${i18n.ts.error}: ${err.id}`;
|
||||||
|
} else if (err.message.startsWith('Unexpected token')) {
|
||||||
|
title = i18n.ts.gotInvalidResponseError;
|
||||||
|
text = i18n.ts.gotInvalidResponseErrorDescription;
|
||||||
}
|
}
|
||||||
alert({
|
alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
|
|
@ -73,7 +73,13 @@
|
||||||
</FormSection>
|
</FormSection>
|
||||||
<FormSection>
|
<FormSection>
|
||||||
<template #label><Mfm text="$[jelly ❤]"/> {{ i18n.ts._aboutMisskey.patrons }}</template>
|
<template #label><Mfm text="$[jelly ❤]"/> {{ i18n.ts._aboutMisskey.patrons }}</template>
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); grid-gap: 12px;">
|
<div :class="$style.patronsWithIcon">
|
||||||
|
<div v-for="patron in patronsWithIcon" :class="$style.patronWithIcon">
|
||||||
|
<img :src="patron.icon" :class="$style.patronIcon">
|
||||||
|
<span :class="$style.patronName">{{ patron.name }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 16px; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); grid-gap: 12px;">
|
||||||
<div v-for="patron in patrons" :key="patron">{{ patron }}</div>
|
<div v-for="patron in patrons" :key="patron">{{ patron }}</div>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ i18n.ts._aboutMisskey.morePatrons }}</p>
|
<p>{{ i18n.ts._aboutMisskey.morePatrons }}</p>
|
||||||
|
@ -99,6 +105,14 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
import { claimAchievement, claimedAchievements } from '@/scripts/achievements';
|
import { claimAchievement, claimedAchievements } from '@/scripts/achievements';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
|
||||||
|
const patronsWithIcon = [{
|
||||||
|
name: 'カイヤン',
|
||||||
|
icon: 'https://misskey-hub.net/patrons/a2820716883e408cb87773e377ce7c8d.jpg',
|
||||||
|
}, {
|
||||||
|
name: 'だれかさん',
|
||||||
|
icon: 'https://misskey-hub.net/patrons/f7409b5e5a88477a9b9d740c408de125.jpg',
|
||||||
|
}];
|
||||||
|
|
||||||
const patrons = [
|
const patrons = [
|
||||||
'まっちゃとーにゅ',
|
'まっちゃとーにゅ',
|
||||||
'mametsuko',
|
'mametsuko',
|
||||||
|
@ -352,4 +366,27 @@ definePageMetadata({
|
||||||
.contributorUsername {
|
.contributorUsername {
|
||||||
margin-left: 12px;
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.patronsWithIcon {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
|
grid-gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patronWithIcon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px;
|
||||||
|
background: var(--buttonBg);
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patronIcon {
|
||||||
|
width: 24px;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patronName {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<MkInput v-model="ad.ratio" type="number">
|
<MkInput v-model="ad.ratio" type="number">
|
||||||
<template #label>{{ i18n.ts.ratio }}</template>
|
<template #label>{{ i18n.ts.ratio }}</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput v-model="ad.expiresAt" type="date">
|
<MkInput v-model="ad.expiresAt" type="datetime-local">
|
||||||
<template #label>{{ i18n.ts.expiration }}</template>
|
<template #label>{{ i18n.ts.expiration }}</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
</FormSplit>
|
</FormSplit>
|
||||||
|
@ -61,7 +61,12 @@ import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
let ads: any[] = $ref([]);
|
let ads: any[] = $ref([]);
|
||||||
|
|
||||||
os.api('admin/ad/list').then(adsResponse => {
|
os.api('admin/ad/list').then(adsResponse => {
|
||||||
ads = adsResponse;
|
ads = adsResponse.map(r => {
|
||||||
|
return {
|
||||||
|
...r,
|
||||||
|
expiresAt: new Date(r.expiresAt).toISOString().slice(0, 16),
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function add() {
|
function add() {
|
||||||
|
|
|
@ -77,6 +77,8 @@ export default defineComponent({
|
||||||
accepted() {
|
accepted() {
|
||||||
this.state = 'accepted';
|
this.state = 'accepted';
|
||||||
if (this.session.app.callbackUrl) {
|
if (this.session.app.callbackUrl) {
|
||||||
|
const url = new URL(this.session.app.callbackUrl);
|
||||||
|
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
|
||||||
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`;
|
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}`;
|
||||||
}
|
}
|
||||||
}, onLogin(res) {
|
}, onLogin(res) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ async function accept(): Promise<void> {
|
||||||
state = 'accepted';
|
state = 'accepted';
|
||||||
if (props.callback) {
|
if (props.callback) {
|
||||||
const cbUrl = new URL(props.callback);
|
const cbUrl = new URL(props.callback);
|
||||||
if (!['http:', 'https:'].includes(cbUrl.protocol)) throw new Error('invalid url');
|
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(cbUrl.protocol)) throw new Error('invalid url');
|
||||||
cbUrl.searchParams.set('session', props.session);
|
cbUrl.searchParams.set('session', props.session);
|
||||||
location.href = cbUrl.href;
|
location.href = cbUrl.href;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,12 +127,11 @@ hr {
|
||||||
}
|
}
|
||||||
|
|
||||||
.ti {
|
.ti {
|
||||||
vertical-align: -14%;
|
vertical-align: -12%;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
display: inline-block;
|
font-size: 128%;
|
||||||
font-size: 130%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,10 +142,10 @@ mainRouter.on('change', () => {
|
||||||
document.documentElement.style.overflowY = 'scroll';
|
document.documentElement.style.overflowY = 'scroll';
|
||||||
|
|
||||||
if (window.innerWidth > 1024) {
|
if (window.innerWidth > 1024) {
|
||||||
const tempUI = miLocalStorage.getItem('ui_temp')
|
const tempUI = miLocalStorage.getItem('ui_temp');
|
||||||
if (tempUI) {
|
if (tempUI) {
|
||||||
miLocalStorage.setItem('ui', tempUI)
|
miLocalStorage.setItem('ui', tempUI);
|
||||||
miLocalStorage.removeItem('ui_temp')
|
miLocalStorage.removeItem('ui_temp');
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue