mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 08:13:10 +02:00
Merge branch 'develop'
This commit is contained in:
commit
3d68a0988b
37 changed files with 546 additions and 209 deletions
|
@ -704,6 +704,11 @@ editCode: "Code bearbeiten"
|
||||||
apply: "Anwenden"
|
apply: "Anwenden"
|
||||||
receiveAnnouncementFromInstance: "E-Mail-Benachrichtigungen von dieser Instanz empfangen"
|
receiveAnnouncementFromInstance: "E-Mail-Benachrichtigungen von dieser Instanz empfangen"
|
||||||
emailNotification: "E-Mail-Benachrichtigungen"
|
emailNotification: "E-Mail-Benachrichtigungen"
|
||||||
|
inChannelSearch: "In Kanal suchen"
|
||||||
|
useReactionPickerForContextMenu: "Reaktionsauswahl durch Rechtsklick öffnen"
|
||||||
|
jumpToSpecifiedDate: "Zu bestimmtem Datum springen"
|
||||||
|
showingPastTimeline: "Momentan wird eine alte Chronik angezeigt"
|
||||||
|
clear: "Zurückkehren"
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "Du hast einen neuen Follower"
|
title: "Du hast einen neuen Follower"
|
||||||
|
|
|
@ -704,6 +704,11 @@ editCode: "Edit code"
|
||||||
apply: "Apply"
|
apply: "Apply"
|
||||||
receiveAnnouncementFromInstance: "Receive Email notifications from this instance"
|
receiveAnnouncementFromInstance: "Receive Email notifications from this instance"
|
||||||
emailNotification: "Email notifications"
|
emailNotification: "Email notifications"
|
||||||
|
inChannelSearch: "Search in channel"
|
||||||
|
useReactionPickerForContextMenu: "Open reaction picker on right-click"
|
||||||
|
jumpToSpecifiedDate: "Jump to specific date"
|
||||||
|
showingPastTimeline: "Currently displaying an old timeline"
|
||||||
|
clear: "Return"
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "You've got a new follower"
|
title: "You've got a new follower"
|
||||||
|
|
|
@ -705,6 +705,11 @@ apply: "適用"
|
||||||
receiveAnnouncementFromInstance: "インスタンスからのお知らせを受け取る"
|
receiveAnnouncementFromInstance: "インスタンスからのお知らせを受け取る"
|
||||||
emailNotification: "メール通知"
|
emailNotification: "メール通知"
|
||||||
inChannelSearch: "チャンネル内検索"
|
inChannelSearch: "チャンネル内検索"
|
||||||
|
useReactionPickerForContextMenu: "右クリックでリアクションピッカーを開く"
|
||||||
|
typingUsers: "{users}が入力中"
|
||||||
|
jumpToSpecifiedDate: "特定の日付にジャンプ"
|
||||||
|
showingPastTimeline: "過去のタイムラインを表示しています"
|
||||||
|
clear: "クリア"
|
||||||
|
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
|
|
|
@ -704,6 +704,7 @@ editCode: "Редактировать исходный текст"
|
||||||
apply: "Применить"
|
apply: "Применить"
|
||||||
receiveAnnouncementFromInstance: "Получать оповещения с инстанса"
|
receiveAnnouncementFromInstance: "Получать оповещения с инстанса"
|
||||||
emailNotification: "Уведомления по электронной почте"
|
emailNotification: "Уведомления по электронной почте"
|
||||||
|
inChannelSearch: "Поиск по каналу"
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "Новый подписчик"
|
title: "Новый подписчик"
|
||||||
|
|
|
@ -309,7 +309,7 @@ monthX: "{month}月"
|
||||||
yearX: "{year}年"
|
yearX: "{year}年"
|
||||||
pages: "页面"
|
pages: "页面"
|
||||||
integration: "关联"
|
integration: "关联"
|
||||||
connectSerice: "已连接"
|
connectSerice: "连接"
|
||||||
disconnectSerice: "断开连接"
|
disconnectSerice: "断开连接"
|
||||||
enableLocalTimeline: "启用本地时间线功能"
|
enableLocalTimeline: "启用本地时间线功能"
|
||||||
enableGlobalTimeline: "启用全局时间线"
|
enableGlobalTimeline: "启用全局时间线"
|
||||||
|
@ -321,7 +321,7 @@ proxyRemoteFiles: "代理远程文件"
|
||||||
proxyRemoteFilesDescription: "启用此设置后,由于超出存储容量而导致未保存被删除的远程文件将被本地代理,并且会生成缩略图。不会影响服务器的存储。"
|
proxyRemoteFilesDescription: "启用此设置后,由于超出存储容量而导致未保存被删除的远程文件将被本地代理,并且会生成缩略图。不会影响服务器的存储。"
|
||||||
driveCapacityPerLocalAccount: "每个用户的网盘空间"
|
driveCapacityPerLocalAccount: "每个用户的网盘空间"
|
||||||
driveCapacityPerRemoteAccount: "每个远程用户的网盘容量"
|
driveCapacityPerRemoteAccount: "每个远程用户的网盘容量"
|
||||||
inMb: "以兆字节(Mbps)为单位"
|
inMb: "以兆字节(MegaByte)为单位"
|
||||||
iconUrl: "图标URL"
|
iconUrl: "图标URL"
|
||||||
bannerUrl: "Banner URL"
|
bannerUrl: "Banner URL"
|
||||||
basicInfo: "基本信息"
|
basicInfo: "基本信息"
|
||||||
|
@ -579,7 +579,7 @@ smtpPort: "端口"
|
||||||
smtpUser: "用户名"
|
smtpUser: "用户名"
|
||||||
smtpPass: "密码"
|
smtpPass: "密码"
|
||||||
emptyToDisableSmtpAuth: "用户名和密码留空可以禁用SMTP验证"
|
emptyToDisableSmtpAuth: "用户名和密码留空可以禁用SMTP验证"
|
||||||
smtpSecure: "在 SMTP 连接中使用隐式 SSL / TLS"
|
smtpSecure: "在 SMTP 连接中默认使用 SSL / TLS"
|
||||||
smtpSecureInfo: "使用STARTTLS时关闭。"
|
smtpSecureInfo: "使用STARTTLS时关闭。"
|
||||||
testEmail: "邮件发送测试"
|
testEmail: "邮件发送测试"
|
||||||
wordMute: "文字屏蔽"
|
wordMute: "文字屏蔽"
|
||||||
|
@ -638,8 +638,8 @@ repliedCount: "回复数"
|
||||||
renotedCount: "转发数"
|
renotedCount: "转发数"
|
||||||
followingCount: "正在关注数量"
|
followingCount: "正在关注数量"
|
||||||
followersCount: "关注者数量"
|
followersCount: "关注者数量"
|
||||||
sentReactionsCount: "发送反应数"
|
sentReactionsCount: "发送回应数"
|
||||||
receivedReactionsCount: "收到反应数"
|
receivedReactionsCount: "收到回应数"
|
||||||
pollVotesCount: "问卷调查的投票数"
|
pollVotesCount: "问卷调查的投票数"
|
||||||
pollVotedCount: "问卷调查的被投票数"
|
pollVotedCount: "问卷调查的被投票数"
|
||||||
yes: "是"
|
yes: "是"
|
||||||
|
@ -704,6 +704,12 @@ editCode: "编辑代码"
|
||||||
apply: "应用"
|
apply: "应用"
|
||||||
receiveAnnouncementFromInstance: "从实例接收通知"
|
receiveAnnouncementFromInstance: "从实例接收通知"
|
||||||
emailNotification: "邮件通知"
|
emailNotification: "邮件通知"
|
||||||
|
inChannelSearch: "频道内搜索"
|
||||||
|
useReactionPickerForContextMenu: "单击右键打开回应工具栏"
|
||||||
|
typingUsers: "{users}正在输入"
|
||||||
|
jumpToSpecifiedDate: "跳转到特定日期"
|
||||||
|
showingPastTimeline: "显示过去的时间线"
|
||||||
|
clear: "清除"
|
||||||
_email:
|
_email:
|
||||||
_follow:
|
_follow:
|
||||||
title: "你有新的关注者"
|
title: "你有新的关注者"
|
||||||
|
|
34
package.json
34
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
"author": "syuilo <syuilotan@yahoo.co.jp>",
|
||||||
"version": "12.70.0",
|
"version": "12.71.0",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -62,9 +62,9 @@
|
||||||
"@types/is-url": "1.2.28",
|
"@types/is-url": "1.2.28",
|
||||||
"@types/js-yaml": "4.0.0",
|
"@types/js-yaml": "4.0.0",
|
||||||
"@types/jsdom": "16.2.6",
|
"@types/jsdom": "16.2.6",
|
||||||
"@types/jsonld": "1.5.2",
|
"@types/jsonld": "1.5.3",
|
||||||
"@types/katex": "0.11.0",
|
"@types/katex": "0.11.0",
|
||||||
"@types/koa": "2.11.7",
|
"@types/koa": "2.13.0",
|
||||||
"@types/koa-bodyparser": "4.3.0",
|
"@types/koa-bodyparser": "4.3.0",
|
||||||
"@types/koa-cors": "0.0.0",
|
"@types/koa-cors": "0.0.0",
|
||||||
"@types/koa-favicon": "2.0.19",
|
"@types/koa-favicon": "2.0.19",
|
||||||
|
@ -77,8 +77,8 @@
|
||||||
"@types/koa__router": "8.0.4",
|
"@types/koa__router": "8.0.4",
|
||||||
"@types/markdown-it": "12.0.1",
|
"@types/markdown-it": "12.0.1",
|
||||||
"@types/matter-js": "0.14.10",
|
"@types/matter-js": "0.14.10",
|
||||||
"@types/mocha": "8.2.0",
|
"@types/mocha": "8.2.1",
|
||||||
"@types/node": "14.14.25",
|
"@types/node": "14.14.31",
|
||||||
"@types/node-fetch": "2.5.8",
|
"@types/node-fetch": "2.5.8",
|
||||||
"@types/nodemailer": "6.4.0",
|
"@types/nodemailer": "6.4.0",
|
||||||
"@types/nprogress": "0.2.0",
|
"@types/nprogress": "0.2.0",
|
||||||
|
@ -110,23 +110,23 @@
|
||||||
"@typescript-eslint/parser": "4.14.2",
|
"@typescript-eslint/parser": "4.14.2",
|
||||||
"@vue/compiler-sfc": "3.0.5",
|
"@vue/compiler-sfc": "3.0.5",
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
"apexcharts": "3.24.0",
|
"apexcharts": "3.25.0",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"aws-sdk": "2.840.0",
|
"aws-sdk": "2.848.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "1.1.3",
|
"blurhash": "1.1.3",
|
||||||
"broadcast-channel": "3.4.1",
|
"broadcast-channel": "3.4.1",
|
||||||
"bull": "3.20.1",
|
"bull": "3.20.1",
|
||||||
"cafy": "15.2.1",
|
"cafy": "15.2.1",
|
||||||
"cbor": "6.0.1",
|
"cbor": "7.0.1",
|
||||||
"chalk": "4.1.0",
|
"chalk": "4.1.0",
|
||||||
"chart.js": "2.9.4",
|
"chart.js": "2.9.4",
|
||||||
"cli-highlight": "2.1.10",
|
"cli-highlight": "2.1.10",
|
||||||
"commander": "4.1.1",
|
"commander": "4.1.1",
|
||||||
"content-disposition": "0.5.3",
|
"content-disposition": "0.5.3",
|
||||||
"core-js": "3.8.3",
|
"core-js": "3.9.0",
|
||||||
"crc-32": "1.2.0",
|
"crc-32": "1.2.0",
|
||||||
"css-loader": "5.0.2",
|
"css-loader": "5.0.2",
|
||||||
"cssnano": "4.1.10",
|
"cssnano": "4.1.10",
|
||||||
|
@ -134,8 +134,8 @@
|
||||||
"diskusage": "1.1.3",
|
"diskusage": "1.1.3",
|
||||||
"double-ended-queue": "2.1.0-0",
|
"double-ended-queue": "2.1.0-0",
|
||||||
"escape-regexp": "0.0.1",
|
"escape-regexp": "0.0.1",
|
||||||
"eslint": "7.19.0",
|
"eslint": "7.20.0",
|
||||||
"eslint-plugin-vue": "7.5.0",
|
"eslint-plugin-vue": "7.6.0",
|
||||||
"eventemitter3": "4.0.7",
|
"eventemitter3": "4.0.7",
|
||||||
"feed": "4.2.2",
|
"feed": "4.2.2",
|
||||||
"fibers": "5.0.0",
|
"fibers": "5.0.0",
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
"jsdom": "16.4.0",
|
"jsdom": "16.4.0",
|
||||||
"json5": "2.2.0",
|
"json5": "2.2.0",
|
||||||
"json5-loader": "4.0.1",
|
"json5-loader": "4.0.1",
|
||||||
"jsonld": "3.3.0",
|
"jsonld": "4.0.1",
|
||||||
"jsrsasign": "8.0.20",
|
"jsrsasign": "8.0.20",
|
||||||
"katex": "0.12.0",
|
"katex": "0.12.0",
|
||||||
"koa": "2.13.1",
|
"koa": "2.13.1",
|
||||||
|
@ -194,7 +194,7 @@
|
||||||
"parsimmon": "1.16.0",
|
"parsimmon": "1.16.0",
|
||||||
"pg": "8.5.1",
|
"pg": "8.5.1",
|
||||||
"portscanner": "2.2.0",
|
"portscanner": "2.2.0",
|
||||||
"postcss": "8.2.5",
|
"postcss": "8.2.6",
|
||||||
"postcss-loader": "5.0.0",
|
"postcss-loader": "5.0.0",
|
||||||
"prismjs": "1.23.0",
|
"prismjs": "1.23.0",
|
||||||
"probe-image-size": "6.0.0",
|
"probe-image-size": "6.0.0",
|
||||||
|
@ -218,7 +218,7 @@
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"rndstr": "1.0.0",
|
"rndstr": "1.0.0",
|
||||||
"s-age": "1.1.2",
|
"s-age": "1.1.2",
|
||||||
"sass": "1.32.6",
|
"sass": "1.32.8",
|
||||||
"sass-loader": "11.0.1",
|
"sass-loader": "11.0.1",
|
||||||
"seedrandom": "3.0.5",
|
"seedrandom": "3.0.5",
|
||||||
"sharp": "0.27.1",
|
"sharp": "0.27.1",
|
||||||
|
@ -234,11 +234,11 @@
|
||||||
"throttle-debounce": "3.0.1",
|
"throttle-debounce": "3.0.1",
|
||||||
"tinycolor2": "1.4.2",
|
"tinycolor2": "1.4.2",
|
||||||
"tmp": "0.2.1",
|
"tmp": "0.2.1",
|
||||||
"ts-loader": "8.0.16",
|
"ts-loader": "8.0.17",
|
||||||
"ts-node": "9.1.1",
|
"ts-node": "9.1.1",
|
||||||
"tslint": "6.1.3",
|
"tslint": "6.1.3",
|
||||||
"tslint-sonarts": "1.9.0",
|
"tslint-sonarts": "1.9.0",
|
||||||
"typeorm": "0.2.30",
|
"typeorm": "0.2.31",
|
||||||
"typescript": "4.1.5",
|
"typescript": "4.1.5",
|
||||||
"ulid": "2.3.0",
|
"ulid": "2.3.0",
|
||||||
"url-loader": "4.1.1",
|
"url-loader": "4.1.1",
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
"vue-style-loader": "4.1.2",
|
"vue-style-loader": "4.1.2",
|
||||||
"vuedraggable": "4.0.1",
|
"vuedraggable": "4.0.1",
|
||||||
"web-push": "3.4.4",
|
"web-push": "3.4.4",
|
||||||
"webpack": "5.21.2",
|
"webpack": "5.23.0",
|
||||||
"webpack-cli": "4.5.0",
|
"webpack-cli": "4.5.0",
|
||||||
"websocket": "1.0.33",
|
"websocket": "1.0.33",
|
||||||
"ws": "7.4.3",
|
"ws": "7.4.3",
|
||||||
|
|
|
@ -756,7 +756,13 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
if (isLink(e.target)) return;
|
if (isLink(e.target)) return;
|
||||||
if (window.getSelection().toString() !== '') return;
|
if (window.getSelection().toString() !== '') return;
|
||||||
|
|
||||||
|
if (this.$store.state.useReactionPickerForContextMenu) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.react();
|
||||||
|
} else {
|
||||||
os.contextMenu(this.getMenu(), e).then(this.focus);
|
os.contextMenu(this.getMenu(), e).then(this.focus);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
menu(viaKeyboard = false) {
|
menu(viaKeyboard = false) {
|
||||||
|
|
|
@ -731,7 +731,13 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
if (isLink(e.target)) return;
|
if (isLink(e.target)) return;
|
||||||
if (window.getSelection().toString() !== '') return;
|
if (window.getSelection().toString() !== '') return;
|
||||||
|
|
||||||
|
if (this.$store.state.useReactionPickerForContextMenu) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.react();
|
||||||
|
} else {
|
||||||
os.contextMenu(this.getMenu(), e).then(this.focus);
|
os.contextMenu(this.getMenu(), e).then(this.focus);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
menu(viaKeyboard = false) {
|
menu(viaKeyboard = false) {
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
<MkError v-if="error" @retry="init()"/>
|
<MkError v-if="error" @retry="init()"/>
|
||||||
|
|
||||||
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
|
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
|
||||||
<button class="_buttonPrimary" @click="fetchMoreFeature" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
<MkButton style="margin: 0 auto;" @click="fetchMoreFeature" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||||
</button>
|
</MkButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
|
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
|
||||||
|
@ -19,10 +19,10 @@
|
||||||
</XList>
|
</XList>
|
||||||
|
|
||||||
<div v-show="more && !reversed" style="margin-top: var(--margin);">
|
<div v-show="more && !reversed" style="margin-top: var(--margin);">
|
||||||
<button class="_buttonPrimary" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
<MkButton style="margin: 0 auto;" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||||
</button>
|
</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,10 +32,11 @@ import { defineComponent } from 'vue';
|
||||||
import paging from '@/scripts/paging';
|
import paging from '@/scripts/paging';
|
||||||
import XNote from './note.vue';
|
import XNote from './note.vue';
|
||||||
import XList from './date-separated-list.vue';
|
import XList from './date-separated-list.vue';
|
||||||
|
import MkButton from '@/components/ui/button.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XNote, XList,
|
XNote, XList, MkButton,
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [
|
mixins: [
|
||||||
|
|
|
@ -70,6 +70,7 @@ import * as os from '@/os';
|
||||||
import { selectFile } from '@/scripts/select-file';
|
import { selectFile } from '@/scripts/select-file';
|
||||||
import { notePostInterruptors, postFormActions } from '@/store';
|
import { notePostInterruptors, postFormActions } from '@/store';
|
||||||
import { isMobile } from '@/scripts/is-mobile';
|
import { isMobile } from '@/scripts/is-mobile';
|
||||||
|
import { throttle } from 'throttle-debounce';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -144,6 +145,11 @@ export default defineComponent({
|
||||||
quoteId: null,
|
quoteId: null,
|
||||||
recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
|
recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
|
||||||
imeText: '',
|
imeText: '',
|
||||||
|
typing: throttle(3000, () => {
|
||||||
|
if (this.channel) {
|
||||||
|
os.stream.send('typingOnChannel', { channel: this.channel.id });
|
||||||
|
}
|
||||||
|
}),
|
||||||
postFormActions,
|
postFormActions,
|
||||||
faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
|
faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
|
||||||
};
|
};
|
||||||
|
@ -434,10 +440,12 @@ export default defineComponent({
|
||||||
onKeydown(e: KeyboardEvent) {
|
onKeydown(e: KeyboardEvent) {
|
||||||
if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
|
if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
|
||||||
if (e.which === 27) this.$emit('esc');
|
if (e.which === 27) this.$emit('esc');
|
||||||
|
this.typing();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCompositionUpdate(e: CompositionEvent) {
|
onCompositionUpdate(e: CompositionEvent) {
|
||||||
this.imeText = e.data;
|
this.imeText = e.data;
|
||||||
|
this.typing();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCompositionEnd(e: CompositionEvent) {
|
onCompositionEnd(e: CompositionEvent) {
|
||||||
|
|
|
@ -70,6 +70,7 @@ export default defineComponent({
|
||||||
// TODO: ResizeObserver無くしたい
|
// TODO: ResizeObserver無くしたい
|
||||||
new ResizeObserver((entries, observer) => {
|
new ResizeObserver((entries, observer) => {
|
||||||
const rect = this.src.getBoundingClientRect();
|
const rect = this.src.getBoundingClientRect();
|
||||||
|
|
||||||
const width = popover.offsetWidth;
|
const width = popover.offsetWidth;
|
||||||
const height = popover.offsetHeight;
|
const height = popover.offsetHeight;
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,9 @@ import { reloadChannel } from '@/scripts/unison-reload';
|
||||||
|
|
||||||
console.info(`Misskey v${version}`);
|
console.info(`Misskey v${version}`);
|
||||||
|
|
||||||
|
// boot.jsのやつを解除
|
||||||
|
window.onerror = null;
|
||||||
|
|
||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
console.warn('Development mode!!!');
|
console.warn('Development mode!!!');
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
v-model="text"
|
v-model="text"
|
||||||
ref="text"
|
ref="text"
|
||||||
@keypress="onKeypress"
|
@keypress="onKeypress"
|
||||||
|
@compositionupdate="onCompositionUpdate"
|
||||||
@paste="onPaste"
|
@paste="onPaste"
|
||||||
:placeholder="$ts.inputMessageHere"
|
:placeholder="$ts.inputMessageHere"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
@ -29,6 +30,7 @@ import { formatTimeString } from '../../../misc/format-time-string';
|
||||||
import { selectFile } from '@/scripts/select-file';
|
import { selectFile } from '@/scripts/select-file';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { Autocomplete } from '@/scripts/autocomplete';
|
import { Autocomplete } from '@/scripts/autocomplete';
|
||||||
|
import { throttle } from 'throttle-debounce';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
|
@ -46,6 +48,9 @@ export default defineComponent({
|
||||||
text: null,
|
text: null,
|
||||||
file: null,
|
file: null,
|
||||||
sending: false,
|
sending: false,
|
||||||
|
typing: throttle(3000, () => {
|
||||||
|
os.stream.send('typingOnMessaging', this.user ? { partner: this.user.id } : { group: this.group.id });
|
||||||
|
}),
|
||||||
faPaperPlane, faPhotoVideo, faLaughSquint
|
faPaperPlane, faPhotoVideo, faLaughSquint
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -147,11 +152,16 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeypress(e) {
|
onKeypress(e) {
|
||||||
|
this.typing();
|
||||||
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey) && this.canSend) {
|
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey) && this.canSend) {
|
||||||
this.send();
|
this.send();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onCompositionUpdate() {
|
||||||
|
this.typing();
|
||||||
|
},
|
||||||
|
|
||||||
chooseFile(e) {
|
chooseFile(e) {
|
||||||
selectFile(e.currentTarget || e.target, this.$ts.selectFile, false).then(file => {
|
selectFile(e.currentTarget || e.target, this.$ts.selectFile, false).then(file => {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
|
|
@ -16,6 +16,14 @@
|
||||||
</XList>
|
</XList>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
|
<div class="typers" v-if="typers.length > 0">
|
||||||
|
<I18n :src="$ts.typingUsers" text-tag="span" class="users">
|
||||||
|
<template #users>
|
||||||
|
<b v-for="user in typers" :key="user.id" class="user">{{ user.username }}</b>
|
||||||
|
</template>
|
||||||
|
</I18n>
|
||||||
|
<MkEllipsis/>
|
||||||
|
</div>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div class="new-message" v-show="showIndicator">
|
<div class="new-message" v-show="showIndicator">
|
||||||
<button class="_buttonPrimary" @click="onIndicatorClick"><i><Fa :icon="faArrowCircleDown"/></i>{{ $ts.newMessageExists }}</button>
|
<button class="_buttonPrimary" @click="onIndicatorClick"><i><Fa :icon="faArrowCircleDown"/></i>{{ $ts.newMessageExists }}</button>
|
||||||
|
@ -86,6 +94,7 @@ const Component = defineComponent({
|
||||||
connection: null,
|
connection: null,
|
||||||
showIndicator: false,
|
showIndicator: false,
|
||||||
timer: null,
|
timer: null,
|
||||||
|
typers: [],
|
||||||
ilObserver: new IntersectionObserver(
|
ilObserver: new IntersectionObserver(
|
||||||
(entries) => entries.some((entry) => entry.isIntersecting)
|
(entries) => entries.some((entry) => entry.isIntersecting)
|
||||||
&& !this.fetching
|
&& !this.fetching
|
||||||
|
@ -142,6 +151,9 @@ const Component = defineComponent({
|
||||||
this.connection.on('message', this.onMessage);
|
this.connection.on('message', this.onMessage);
|
||||||
this.connection.on('read', this.onRead);
|
this.connection.on('read', this.onRead);
|
||||||
this.connection.on('deleted', this.onDeleted);
|
this.connection.on('deleted', this.onDeleted);
|
||||||
|
this.connection.on('typers', typers => {
|
||||||
|
this.typers = typers.filter(u => u.id !== this.$i.id);
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', this.onVisibilitychange);
|
document.addEventListener('visibilitychange', this.onVisibilitychange);
|
||||||
|
|
||||||
|
@ -397,6 +409,7 @@ export default Component;
|
||||||
|
|
||||||
> footer {
|
> footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
> .new-message {
|
> .new-message {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -422,6 +435,25 @@ export default Component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .typers {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
padding: 0 8px 0 8px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--fgTransparentWeak);
|
||||||
|
|
||||||
|
> .users {
|
||||||
|
> .user + .user:before {
|
||||||
|
content: ", ";
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .user:last-of-type:after {
|
||||||
|
content: " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}).then(({ canceled, result: password }) => {
|
}).then(({ canceled, result: password }) => {
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
os.api('i/update-email', {
|
os.apiWithDialog('i/update-email', {
|
||||||
password: password,
|
password: password,
|
||||||
email: this.emailAddress,
|
email: this.emailAddress,
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<template #label>{{ $ts.behavior }}</template>
|
<template #label>{{ $ts.behavior }}</template>
|
||||||
<FormSwitch v-model:value="imageNewTab">{{ $ts.openImageInNewTab }}</FormSwitch>
|
<FormSwitch v-model:value="imageNewTab">{{ $ts.openImageInNewTab }}</FormSwitch>
|
||||||
<FormSwitch v-model:value="enableInfiniteScroll">{{ $ts.enableInfiniteScroll }}</FormSwitch>
|
<FormSwitch v-model:value="enableInfiniteScroll">{{ $ts.enableInfiniteScroll }}</FormSwitch>
|
||||||
|
<FormSwitch v-model:value="useReactionPickerForContextMenu">{{ $ts.useReactionPickerForContextMenu }}</FormSwitch>
|
||||||
<FormSwitch v-model:value="disablePagesScript">{{ $ts.disablePagesScript }}</FormSwitch>
|
<FormSwitch v-model:value="disablePagesScript">{{ $ts.disablePagesScript }}</FormSwitch>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
@ -144,6 +145,7 @@ export default defineComponent({
|
||||||
chatOpenBehavior: ColdDeviceStorage.makeGetterSetter('chatOpenBehavior'),
|
chatOpenBehavior: ColdDeviceStorage.makeGetterSetter('chatOpenBehavior'),
|
||||||
instanceTicker: defaultStore.makeGetterSetter('instanceTicker'),
|
instanceTicker: defaultStore.makeGetterSetter('instanceTicker'),
|
||||||
enableInfiniteScroll: defaultStore.makeGetterSetter('enableInfiniteScroll'),
|
enableInfiniteScroll: defaultStore.makeGetterSetter('enableInfiniteScroll'),
|
||||||
|
useReactionPickerForContextMenu: defaultStore.makeGetterSetter('useReactionPickerForContextMenu'),
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -192,8 +192,6 @@ export default (opts) => ({
|
||||||
this.items = this.items.slice(-opts.displayLimit);
|
this.items = this.items.slice(-opts.displayLimit);
|
||||||
this.more = true;
|
this.more = true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
this.items.push(item);
|
this.items.push(item);
|
||||||
// TODO
|
// TODO
|
||||||
|
|
|
@ -144,6 +144,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||||
where: 'device',
|
where: 'device',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
useReactionPickerForContextMenu: {
|
||||||
|
where: 'device',
|
||||||
|
default: true
|
||||||
|
},
|
||||||
showGapBetweenNotesInTimeline: {
|
showGapBetweenNotesInTimeline: {
|
||||||
where: 'device',
|
where: 'device',
|
||||||
default: true
|
default: true
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return h(TransitionGroup, {
|
return h(this.reversed ? 'div' : TransitionGroup, {
|
||||||
class: 'hmjzthxl',
|
class: 'hmjzthxl',
|
||||||
name: this.reversed ? 'list-reversed' : 'list',
|
name: this.reversed ? 'list-reversed' : 'list',
|
||||||
tag: 'div',
|
tag: 'div',
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="_monospace">
|
<div class="acemodlh _monospace">
|
||||||
<span>
|
<div>
|
||||||
|
<span v-text="y"></span>/<span v-text="m"></span>/<span v-text="d"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<span v-text="hh"></span>
|
<span v-text="hh"></span>
|
||||||
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
||||||
<span v-text="mm"></span>
|
<span v-text="mm"></span>
|
||||||
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span>
|
||||||
<span v-text="ss"></span>
|
<span v-text="ss"></span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -18,6 +21,9 @@ export default defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
clock: null,
|
clock: null,
|
||||||
|
y: null,
|
||||||
|
m: null,
|
||||||
|
d: null,
|
||||||
hh: null,
|
hh: null,
|
||||||
mm: null,
|
mm: null,
|
||||||
ss: null,
|
ss: null,
|
||||||
|
@ -34,6 +40,9 @@ export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
tick() {
|
tick() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
this.y = now.getFullYear().toString();
|
||||||
|
this.m = (now.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
this.d = now.getDate().toString().padStart(2, '0');
|
||||||
this.hh = now.getHours().toString().padStart(2, '0');
|
this.hh = now.getHours().toString().padStart(2, '0');
|
||||||
this.mm = now.getMinutes().toString().padStart(2, '0');
|
this.mm = now.getMinutes().toString().padStart(2, '0');
|
||||||
this.ss = now.getSeconds().toString().padStart(2, '0');
|
this.ss = now.getSeconds().toString().padStart(2, '0');
|
||||||
|
@ -42,3 +51,12 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.acemodlh {
|
||||||
|
opacity: 0.7;
|
||||||
|
font-size: 0.85em;
|
||||||
|
line-height: 1em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -99,6 +99,9 @@
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="instance">{{ instanceName }}</div>
|
<div class="instance">{{ instanceName }}</div>
|
||||||
<XHeaderClock class="clock"/>
|
<XHeaderClock class="clock"/>
|
||||||
|
<button class="_button button timetravel" @click="timetravel" v-tooltip="$ts.jumpToSpecifiedDate">
|
||||||
|
<Fa :icon="faCalendarAlt"/>
|
||||||
|
</button>
|
||||||
<button class="_button button search" v-if="tl.startsWith('channel:') && currentChannel" @click="inChannelSearch" v-tooltip="$ts.inChannelSearch">
|
<button class="_button button search" v-if="tl.startsWith('channel:') && currentChannel" @click="inChannelSearch" v-tooltip="$ts.inChannelSearch">
|
||||||
<Fa :icon="faSearch"/>
|
<Fa :icon="faSearch"/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -114,14 +117,9 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="body">
|
|
||||||
<XTimeline v-if="tl.startsWith('channel:')" src="channel" :key="tl" :channel="tl.replace('channel:', '')"/>
|
<XTimeline class="body" ref="tl" v-if="tl.startsWith('channel:')" src="channel" :key="tl" :channel="tl.replace('channel:', '')"/>
|
||||||
<XTimeline v-else :src="tl" :key="tl"/>
|
<XTimeline class="body" ref="tl" v-else :src="tl" :key="tl"/>
|
||||||
</div>
|
|
||||||
<footer class="footer">
|
|
||||||
<XPostForm v-if="tl.startsWith('channel:')" :key="tl" :channel="tl.replace('channel:', '')"/>
|
|
||||||
<XPostForm v-else/>
|
|
||||||
</footer>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<XSide class="side" ref="side" @open="sideViewOpening = true" @close="sideViewOpening = false"/>
|
<XSide class="side" ref="side" @open="sideViewOpening = true" @close="sideViewOpening = false"/>
|
||||||
|
@ -136,20 +134,20 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, defineAsyncComponent } from 'vue';
|
import { defineComponent, defineAsyncComponent } from 'vue';
|
||||||
import { faLayerGroup, faBars, faHome, faCircle, faWindowMaximize, faColumns, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, faAt, faLink, faEllipsisH, faGlobe } from '@fortawesome/free-solid-svg-icons';
|
import { faLayerGroup, faBars, faHome, faCircle, faWindowMaximize, faColumns, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, faAt, faLink, faEllipsisH, faGlobe } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faBell, faStar as farStar, faEnvelope, faComments } from '@fortawesome/free-regular-svg-icons';
|
import { faBell, faStar as farStar, faEnvelope, faComments, faCalendarAlt } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { instanceName, url } from '@/config';
|
import { instanceName, url } from '@/config';
|
||||||
import XSidebar from '@/components/sidebar.vue';
|
import XSidebar from '@/components/sidebar.vue';
|
||||||
import XWidgets from './widgets.vue';
|
import XWidgets from './widgets.vue';
|
||||||
import XCommon from '../_common_/common.vue';
|
import XCommon from '../_common_/common.vue';
|
||||||
import XSide from './side.vue';
|
import XSide from './side.vue';
|
||||||
import XTimeline from './timeline.vue';
|
import XTimeline from './timeline.vue';
|
||||||
import XPostForm from './post-form.vue';
|
|
||||||
import XHeaderClock from './header-clock.vue';
|
import XHeaderClock from './header-clock.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { router } from '@/router';
|
import { router } from '@/router';
|
||||||
import { sidebarDef } from '@/sidebar';
|
import { sidebarDef } from '@/sidebar';
|
||||||
import { search } from '@/scripts/search';
|
import { search } from '@/scripts/search';
|
||||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||||
|
import { store } from './store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -158,7 +156,6 @@ export default defineComponent({
|
||||||
XWidgets,
|
XWidgets,
|
||||||
XSide, // NOTE: dynamic importするとAsyncComponentWrapperが間に入るせいでref取得できなくて面倒になる
|
XSide, // NOTE: dynamic importするとAsyncComponentWrapperが間に入るせいでref取得できなくて面倒になる
|
||||||
XTimeline,
|
XTimeline,
|
||||||
XPostForm,
|
|
||||||
XHeaderClock,
|
XHeaderClock,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -189,7 +186,7 @@ export default defineComponent({
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tl: 'home',
|
tl: store.state.tl,
|
||||||
lists: null,
|
lists: null,
|
||||||
antennas: null,
|
antennas: null,
|
||||||
followedChannels: null,
|
followedChannels: null,
|
||||||
|
@ -198,7 +195,7 @@ export default defineComponent({
|
||||||
menuDef: sidebarDef,
|
menuDef: sidebarDef,
|
||||||
sideViewOpening: false,
|
sideViewOpening: false,
|
||||||
instanceName,
|
instanceName,
|
||||||
faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, farStar, faAt, faLink, faEllipsisH, faGlobe, faComments, faEnvelope,
|
faLayerGroup, faBars, faBell, faHome, faCircle, faPencilAlt, faShareAlt, faSatelliteDish, faListUl, faSatellite, faCog, faSearch, faPlus, faStar, farStar, faAt, faLink, faEllipsisH, faGlobe, faComments, faEnvelope, faCalendarAlt,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -222,11 +219,12 @@ export default defineComponent({
|
||||||
this.antennas = antennas;
|
this.antennas = antennas;
|
||||||
});
|
});
|
||||||
|
|
||||||
os.api('channels/followed').then(channels => {
|
os.api('channels/followed', { limit: 20 }).then(channels => {
|
||||||
this.followedChannels = channels;
|
this.followedChannels = channels;
|
||||||
});
|
});
|
||||||
|
|
||||||
os.api('channels/featured').then(channels => {
|
// TODO: pagination
|
||||||
|
os.api('channels/featured', { limit: 20 }).then(channels => {
|
||||||
this.featuredChannels = channels;
|
this.featuredChannels = channels;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -236,6 +234,7 @@ export default defineComponent({
|
||||||
this.currentChannel = channel;
|
this.currentChannel = channel;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
store.set('tl', this.tl);
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -248,6 +247,18 @@ export default defineComponent({
|
||||||
os.post();
|
os.post();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async timetravel() {
|
||||||
|
const { canceled, result: date } = await os.dialog({
|
||||||
|
title: this.$ts.date,
|
||||||
|
input: {
|
||||||
|
type: 'date'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (canceled) return;
|
||||||
|
|
||||||
|
this.$refs.tl.timetravel(new Date(date));
|
||||||
|
},
|
||||||
|
|
||||||
search() {
|
search() {
|
||||||
search();
|
search();
|
||||||
},
|
},
|
||||||
|
@ -470,6 +481,9 @@ export default defineComponent({
|
||||||
display: block;
|
display: block;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -581,16 +595,6 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .footer {
|
|
||||||
padding: 0 16px 16px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .body {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .side {
|
> .side {
|
||||||
|
|
|
@ -741,7 +741,13 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
if (isLink(e.target)) return;
|
if (isLink(e.target)) return;
|
||||||
if (window.getSelection().toString() !== '') return;
|
if (window.getSelection().toString() !== '') return;
|
||||||
|
|
||||||
|
if (this.$store.state.useReactionPickerForContextMenu) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.react();
|
||||||
|
} else {
|
||||||
os.contextMenu(this.getMenu(), e).then(this.focus);
|
os.contextMenu(this.getMenu(), e).then(this.focus);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
menu(viaKeyboard = false) {
|
menu(viaKeyboard = false) {
|
||||||
|
@ -1004,7 +1010,7 @@ export default defineComponent({
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
display: block;
|
display: block;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 12px;
|
top: 0;
|
||||||
margin: 0 14px 0 0;
|
margin: 0 14px 0 0;
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
|
@ -1085,6 +1091,7 @@ export default defineComponent({
|
||||||
|
|
||||||
> .poll {
|
> .poll {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .renote {
|
> .renote {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="" :ref="mounted">
|
<div class="">
|
||||||
<div class="_fullinfo" v-if="empty">
|
<div class="_fullinfo" v-if="empty">
|
||||||
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
|
||||||
<div>{{ $ts.noNotes }}</div>
|
<div>{{ $ts.noNotes }}</div>
|
||||||
|
@ -8,10 +8,10 @@
|
||||||
<MkError v-if="error" @retry="init()"/>
|
<MkError v-if="error" @retry="init()"/>
|
||||||
|
|
||||||
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
|
<div v-show="more && reversed" style="margin-bottom: var(--margin);">
|
||||||
<button class="_buttonPrimary" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
<MkButton style="margin: 0 auto;" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||||
</button>
|
</MkButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
|
<XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
|
||||||
|
@ -19,10 +19,10 @@
|
||||||
</XList>
|
</XList>
|
||||||
|
|
||||||
<div v-show="more && !reversed" style="margin-top: var(--margin);">
|
<div v-show="more && !reversed" style="margin-top: var(--margin);">
|
||||||
<button class="_buttonPrimary" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
<MkButton style="margin: 0 auto;" v-appear="$store.state.enableInfiniteScroll ? fetchMore : null" @click="fetchMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
|
||||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||||
</button>
|
</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,10 +32,11 @@ import { defineComponent } from 'vue';
|
||||||
import paging from '@/scripts/paging';
|
import paging from '@/scripts/paging';
|
||||||
import XNote from './note.vue';
|
import XNote from './note.vue';
|
||||||
import XList from './date-separated-list.vue';
|
import XList from './date-separated-list.vue';
|
||||||
|
import MkButton from '@/components/ui/button.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XNote, XList,
|
XNote, XList, MkButton,
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [
|
mixins: [
|
||||||
|
|
|
@ -65,6 +65,7 @@ import * as os from '@/os';
|
||||||
import { selectFile } from '@/scripts/select-file';
|
import { selectFile } from '@/scripts/select-file';
|
||||||
import { notePostInterruptors, postFormActions } from '@/store';
|
import { notePostInterruptors, postFormActions } from '@/store';
|
||||||
import { isMobile } from '@/scripts/is-mobile';
|
import { isMobile } from '@/scripts/is-mobile';
|
||||||
|
import { throttle } from 'throttle-debounce';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -131,6 +132,11 @@ export default defineComponent({
|
||||||
quoteId: null,
|
quoteId: null,
|
||||||
recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
|
recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
|
||||||
imeText: '',
|
imeText: '',
|
||||||
|
typing: throttle(3000, () => {
|
||||||
|
if (this.channel) {
|
||||||
|
os.stream.send('typingOnChannel', { channel: this.channel });
|
||||||
|
}
|
||||||
|
}),
|
||||||
postFormActions,
|
postFormActions,
|
||||||
faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
|
faReply, faQuoteRight, faPaperPlane, faTimes, faUpload, faPollH, faGlobe, faHome, faUnlock, faEnvelope, faEyeSlash, faLaughSquint, faPlus, faPhotoVideo, faAt, faBiohazard, faPlug
|
||||||
};
|
};
|
||||||
|
@ -421,10 +427,12 @@ export default defineComponent({
|
||||||
onKeydown(e: KeyboardEvent) {
|
onKeydown(e: KeyboardEvent) {
|
||||||
if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
|
if ((e.which === 10 || e.which === 13) && (e.ctrlKey || e.metaKey) && this.canPost) this.post();
|
||||||
if (e.which === 27) this.$emit('esc');
|
if (e.which === 27) this.$emit('esc');
|
||||||
|
this.typing();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCompositionUpdate(e: CompositionEvent) {
|
onCompositionUpdate(e: CompositionEvent) {
|
||||||
this.imeText = e.data;
|
this.imeText = e.data;
|
||||||
|
this.typing();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCompositionEnd(e: CompositionEvent) {
|
onCompositionEnd(e: CompositionEvent) {
|
||||||
|
|
|
@ -10,4 +10,8 @@ export const store = markRaw(new Storage('chatUi', {
|
||||||
data: Record<string, any>;
|
data: Record<string, any>;
|
||||||
}[]
|
}[]
|
||||||
},
|
},
|
||||||
|
tl: {
|
||||||
|
where: 'deviceAccount',
|
||||||
|
default: 'home'
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -1,8 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="dbiokgaf">
|
<div class="dbiokgaf info" v-if="date">
|
||||||
|
<MkInfo>{{ $ts.showingPastTimeline }} <button class="_textButton clear" @click="timetravel()">{{ $ts.clear }}</button></MkInfo>
|
||||||
|
</div>
|
||||||
|
<div class="dbiokgaf top" v-if="['home', 'local', 'social', 'global'].includes(src)">
|
||||||
|
<XPostForm/>
|
||||||
|
</div>
|
||||||
|
<div class="dbiokgaf tl" ref="body">
|
||||||
<div class="new" v-if="queue > 0" :style="{ width: width + 'px', [pagination.reversed ? 'bottom' : 'top']: pagination.reversed ? bottom + 'px' : top + 'px' }"><button class="_buttonPrimary" @click="goTop()">{{ $ts.newNoteRecived }}</button></div>
|
<div class="new" v-if="queue > 0" :style="{ width: width + 'px', [pagination.reversed ? 'bottom' : 'top']: pagination.reversed ? bottom + 'px' : top + 'px' }"><button class="_buttonPrimary" @click="goTop()">{{ $ts.newNoteRecived }}</button></div>
|
||||||
<XNotes class="tl" ref="tl" :pagination="pagination" @queue="queueUpdated" v-follow="pagination.reversed"/>
|
<XNotes class="tl" ref="tl" :pagination="pagination" @queue="queueUpdated" v-follow="pagination.reversed"/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="dbiokgaf bottom" v-if="src === 'channel'">
|
||||||
|
<div class="typers" v-if="typers.length > 0">
|
||||||
|
<I18n :src="$ts.typingUsers" text-tag="span" class="users">
|
||||||
|
<template #users>
|
||||||
|
<b v-for="user in typers" :key="user.id" class="user">{{ user.username }}</b>
|
||||||
|
</template>
|
||||||
|
</I18n>
|
||||||
|
<MkEllipsis/>
|
||||||
|
</div>
|
||||||
|
<XPostForm :channel="channel"/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -12,10 +29,14 @@ import * as os from '@/os';
|
||||||
import * as sound from '@/scripts/sound';
|
import * as sound from '@/scripts/sound';
|
||||||
import { scrollToBottom, getScrollPosition, getScrollContainer } from '@/scripts/scroll';
|
import { scrollToBottom, getScrollPosition, getScrollContainer } from '@/scripts/scroll';
|
||||||
import follow from '@/directives/follow-append';
|
import follow from '@/directives/follow-append';
|
||||||
|
import XPostForm from './post-form.vue';
|
||||||
|
import MkInfo from '@/components/ui/info.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
XNotes
|
XNotes,
|
||||||
|
XPostForm,
|
||||||
|
MkInfo,
|
||||||
},
|
},
|
||||||
|
|
||||||
directives: {
|
directives: {
|
||||||
|
@ -45,11 +66,6 @@ export default defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
sound: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
emits: ['note', 'queue', 'before', 'after'],
|
emits: ['note', 'queue', 'before', 'after'],
|
||||||
|
@ -69,6 +85,8 @@ export default defineComponent({
|
||||||
width: 0,
|
width: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
typers: [],
|
||||||
|
date: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -78,9 +96,7 @@ export default defineComponent({
|
||||||
|
|
||||||
this.$emit('note');
|
this.$emit('note');
|
||||||
|
|
||||||
if (this.sound) {
|
|
||||||
sound.play(note.userId === this.$i.id ? 'noteMy' : 'note');
|
sound.play(note.userId === this.$i.id ? 'noteMy' : 'note');
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onUserAdded = () => {
|
const onUserAdded = () => {
|
||||||
|
@ -166,6 +182,9 @@ export default defineComponent({
|
||||||
channelId: this.channel
|
channelId: this.channel
|
||||||
});
|
});
|
||||||
this.connection.on('note', prepend);
|
this.connection.on('note', prepend);
|
||||||
|
this.connection.on('typers', typers => {
|
||||||
|
this.typers = this.$i ? typers.filter(u => u.id !== this.$i.id) : typers;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pagination = {
|
this.pagination = {
|
||||||
|
@ -173,7 +192,7 @@ export default defineComponent({
|
||||||
reversed,
|
reversed,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
params: init => ({
|
params: init => ({
|
||||||
untilDate: init ? undefined : (this.date ? this.date.getTime() : undefined),
|
untilDate: this.date?.getTime(),
|
||||||
...this.baseQuery, ...this.query
|
...this.baseQuery, ...this.query
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -190,34 +209,73 @@ export default defineComponent({
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
focus() {
|
focus() {
|
||||||
this.$refs.tl.focus();
|
this.$refs.body.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
goTop() {
|
goTop() {
|
||||||
const container = getScrollContainer(this.$el);
|
const container = getScrollContainer(this.$refs.body);
|
||||||
container.scrollTop = 0;
|
container.scrollTop = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
queueUpdated(q) {
|
queueUpdated(q) {
|
||||||
if (this.$el.offsetWidth !== 0) {
|
if (this.$refs.body.offsetWidth !== 0) {
|
||||||
const rect = this.$el.getBoundingClientRect();
|
const rect = this.$refs.body.getBoundingClientRect();
|
||||||
const scrollTop = getScrollPosition(this.$el);
|
this.width = this.$refs.body.offsetWidth;
|
||||||
this.width = this.$el.offsetWidth;
|
this.top = rect.top;
|
||||||
this.top = rect.top + scrollTop;
|
this.bottom = this.$refs.body.offsetHeight;
|
||||||
this.bottom = this.$el.offsetHeight;
|
|
||||||
}
|
}
|
||||||
this.queue = q;
|
this.queue = q;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
timetravel(date?: Date) {
|
||||||
|
this.date = date;
|
||||||
|
this.$refs.tl.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.dbiokgaf {
|
.dbiokgaf.info{
|
||||||
padding: 16px 0;
|
padding: 16px 16px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: これはノート追加アニメーションによるスクロール発生を抑えるために必要だが、position stickyが効かなくなるので、両者を両立させる良い方法を考える
|
.dbiokgaf.top {
|
||||||
overflow: hidden;
|
padding: 16px 16px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbiokgaf.bottom {
|
||||||
|
padding: 0 16px 16px 16px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> .typers {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
padding: 0 8px 0 8px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
background: var(--panel);
|
||||||
|
border-radius: 0 8px 0 0;
|
||||||
|
color: var(--fgTransparentWeak);
|
||||||
|
|
||||||
|
> .users {
|
||||||
|
> .user + .user:before {
|
||||||
|
content: ", ";
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .user:last-of-type:after {
|
||||||
|
content: " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dbiokgaf.tl {
|
||||||
|
position: relative;
|
||||||
|
padding: 16px 0;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
> .new {
|
> .new {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, defineAsyncComponent } from 'vue';
|
import { defineComponent, defineAsyncComponent } from 'vue';
|
||||||
import XWidgets from '@/components/widgets.vue';
|
import XWidgets from '@/components/widgets.vue';
|
||||||
import { store } from './store.ts';
|
import { store } from './store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -34,6 +34,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
updateWidget({ id, data }) {
|
updateWidget({ id, data }) {
|
||||||
|
// TODO: throttleしたい
|
||||||
store.set('widgets', store.state.widgets.map(w => w.id === id ? {
|
store.set('widgets', store.state.widgets.map(w => w.id === id ? {
|
||||||
...w,
|
...w,
|
||||||
data: data
|
data: data
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import { throttle } from 'throttle-debounce';
|
||||||
import { Form } from '@/scripts/form';
|
import { Form } from '@/scripts/form';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
|
|
||||||
|
@ -21,7 +22,10 @@ export default function <T extends Form>(data: {
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
props: this.widget ? JSON.parse(JSON.stringify(this.widget.data)) : {}
|
props: this.widget ? JSON.parse(JSON.stringify(this.widget.data)) : {},
|
||||||
|
save: throttle(3000, () => {
|
||||||
|
this.$emit('updateProps', this.props);
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -66,10 +70,6 @@ export default function <T extends Form>(data: {
|
||||||
|
|
||||||
this.save();
|
this.save();
|
||||||
},
|
},
|
||||||
|
|
||||||
save() {
|
|
||||||
this.$emit('updateProps', this.props);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,19 @@
|
||||||
<div class="values">
|
<div class="values">
|
||||||
<div>
|
<div>
|
||||||
<div>Process</div>
|
<div>Process</div>
|
||||||
<div>{{ number(inbox.activeSincePrevTick) }}</div>
|
<div :class="{ inc: inbox.activeSincePrevTick > prev.inbox.activeSincePrevTick, dec: inbox.activeSincePrevTick < prev.inbox.activeSincePrevTick }">{{ number(inbox.activeSincePrevTick) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Active</div>
|
<div>Active</div>
|
||||||
<div>{{ number(inbox.active) }}</div>
|
<div :class="{ inc: inbox.active > prev.inbox.active, dec: inbox.active < prev.inbox.active }">{{ number(inbox.active) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Delayed</div>
|
<div>Delayed</div>
|
||||||
<div>{{ number(inbox.delayed) }}</div>
|
<div :class="{ inc: inbox.delayed > prev.inbox.delayed, dec: inbox.delayed < prev.inbox.delayed }">{{ number(inbox.delayed) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Waiting</div>
|
<div>Waiting</div>
|
||||||
<div>{{ number(inbox.waiting) }}</div>
|
<div :class="{ inc: inbox.waiting > prev.inbox.waiting, dec: inbox.waiting < prev.inbox.waiting }">{{ number(inbox.waiting) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,19 +26,19 @@
|
||||||
<div class="values">
|
<div class="values">
|
||||||
<div>
|
<div>
|
||||||
<div>Process</div>
|
<div>Process</div>
|
||||||
<div>{{ number(deliver.activeSincePrevTick) }}</div>
|
<div :class="{ inc: deliver.activeSincePrevTick > prev.deliver.activeSincePrevTick, dec: deliver.activeSincePrevTick < prev.deliver.activeSincePrevTick }">{{ number(deliver.activeSincePrevTick) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Active</div>
|
<div>Active</div>
|
||||||
<div>{{ number(deliver.active) }}</div>
|
<div :class="{ inc: deliver.active > prev.deliver.active, dec: deliver.active < prev.deliver.active }">{{ number(deliver.active) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Delayed</div>
|
<div>Delayed</div>
|
||||||
<div>{{ number(deliver.delayed) }}</div>
|
<div :class="{ inc: deliver.delayed > prev.deliver.delayed, dec: deliver.delayed < prev.deliver.delayed }">{{ number(deliver.delayed) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Waiting</div>
|
<div>Waiting</div>
|
||||||
<div>{{ number(deliver.waiting) }}</div>
|
<div :class="{ inc: deliver.waiting > prev.deliver.waiting, dec: deliver.waiting < prev.deliver.waiting }">{{ number(deliver.waiting) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,10 +79,15 @@ export default defineComponent({
|
||||||
waiting: 0,
|
waiting: 0,
|
||||||
delayed: 0,
|
delayed: 0,
|
||||||
},
|
},
|
||||||
|
prev: {},
|
||||||
faExclamationTriangle,
|
faExclamationTriangle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
for (const domain of ['inbox', 'deliver']) {
|
||||||
|
this.prev[domain] = JSON.parse(JSON.stringify(this[domain]));
|
||||||
|
}
|
||||||
|
|
||||||
this.connection.on('stats', this.onStats);
|
this.connection.on('stats', this.onStats);
|
||||||
this.connection.on('statsLog', this.onStatsLog);
|
this.connection.on('statsLog', this.onStatsLog);
|
||||||
|
|
||||||
|
@ -99,6 +104,7 @@ export default defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
onStats(stats) {
|
onStats(stats) {
|
||||||
for (const domain of ['inbox', 'deliver']) {
|
for (const domain of ['inbox', 'deliver']) {
|
||||||
|
this.prev[domain] = JSON.parse(JSON.stringify(this[domain]));
|
||||||
this[domain].activeSincePrevTick = stats[domain].activeSincePrevTick;
|
this[domain].activeSincePrevTick = stats[domain].activeSincePrevTick;
|
||||||
this[domain].active = stats[domain].active;
|
this[domain].active = stats[domain].active;
|
||||||
this[domain].waiting = stats[domain].waiting;
|
this[domain].waiting = stats[domain].waiting;
|
||||||
|
@ -152,6 +158,16 @@ export default defineComponent({
|
||||||
> div:first-child {
|
> div:first-child {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> div:last-child {
|
||||||
|
&.inc {
|
||||||
|
color: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.dec {
|
||||||
|
color: var(--success);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ export default define(meta, async (ps, user) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region Construct query
|
//#region Construct query
|
||||||
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
|
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
|
||||||
.andWhere('note.channelId = :channelId', { channelId: channel.id })
|
.andWhere('note.channelId = :channelId', { channelId: channel.id })
|
||||||
.leftJoinAndSelect('note.user', 'user')
|
.leftJoinAndSelect('note.user', 'user')
|
||||||
.leftJoinAndSelect('note.channel', 'channel');
|
.leftJoinAndSelect('note.channel', 'channel');
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import autobind from 'autobind-decorator';
|
import autobind from 'autobind-decorator';
|
||||||
import Channel from '../channel';
|
import Channel from '../channel';
|
||||||
import { Notes } from '../../../../models';
|
import { Notes, Users } from '../../../../models';
|
||||||
import { isMutedUserRelated } from '../../../../misc/is-muted-user-related';
|
import { isMutedUserRelated } from '../../../../misc/is-muted-user-related';
|
||||||
import { PackedNote } from '../../../../models/repositories/note';
|
import { PackedNote } from '../../../../models/repositories/note';
|
||||||
|
import { User } from '../../../../models/entities/user';
|
||||||
|
|
||||||
export default class extends Channel {
|
export default class extends Channel {
|
||||||
public readonly chName = 'channel';
|
public readonly chName = 'channel';
|
||||||
public static shouldShare = false;
|
public static shouldShare = false;
|
||||||
public static requireCredential = false;
|
public static requireCredential = false;
|
||||||
private channelId: string;
|
private channelId: string;
|
||||||
|
private typers: Record<User['id'], Date> = {};
|
||||||
|
private emitTypersIntervalId: ReturnType<typeof setInterval>;
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public async init(params: any) {
|
public async init(params: any) {
|
||||||
|
@ -16,6 +19,8 @@ export default class extends Channel {
|
||||||
|
|
||||||
// Subscribe stream
|
// Subscribe stream
|
||||||
this.subscriber.on('notesStream', this.onNote);
|
this.subscriber.on('notesStream', this.onNote);
|
||||||
|
this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent);
|
||||||
|
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -41,9 +46,41 @@ export default class extends Channel {
|
||||||
this.send('note', note);
|
this.send('note', note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private onEvent(data: any) {
|
||||||
|
if (data.type === 'typing') {
|
||||||
|
const id = data.body;
|
||||||
|
const begin = this.typers[id] == null;
|
||||||
|
this.typers[id] = new Date();
|
||||||
|
if (begin) {
|
||||||
|
this.emitTypers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private async emitTypers() {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Remove not typing users
|
||||||
|
for (const [userId, date] of Object.entries(this.typers)) {
|
||||||
|
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
|
||||||
|
}
|
||||||
|
|
||||||
|
const users = await Users.packMany(Object.keys(this.typers), null, { detail: false });
|
||||||
|
|
||||||
|
this.send({
|
||||||
|
type: 'typers',
|
||||||
|
body: users,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public dispose() {
|
public dispose() {
|
||||||
// Unsubscribe events
|
// Unsubscribe events
|
||||||
this.subscriber.off('notesStream', this.onNote);
|
this.subscriber.off('notesStream', this.onNote);
|
||||||
|
this.subscriber.off(`channelStream:${this.channelId}`, this.onEvent);
|
||||||
|
|
||||||
|
clearInterval(this.emitTypersIntervalId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default class extends Channel {
|
||||||
|
|
||||||
private gameId: ReversiGame['id'] | null = null;
|
private gameId: ReversiGame['id'] | null = null;
|
||||||
private watchers: Record<User['id'], Date> = {};
|
private watchers: Record<User['id'], Date> = {};
|
||||||
private emitWatchersIntervalId: any;
|
private emitWatchersIntervalId: ReturnType<typeof setInterval>;
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public async init(params: any) {
|
public async init(params: any) {
|
||||||
|
|
|
@ -12,6 +12,9 @@ export default class extends Channel {
|
||||||
private otherpartyId: string | null;
|
private otherpartyId: string | null;
|
||||||
private otherparty?: User;
|
private otherparty?: User;
|
||||||
private groupId: string | null;
|
private groupId: string | null;
|
||||||
|
private subCh: string;
|
||||||
|
private typers: Record<User['id'], Date> = {};
|
||||||
|
private emitTypersIntervalId: ReturnType<typeof setInterval>;
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public async init(params: any) {
|
public async init(params: any) {
|
||||||
|
@ -31,14 +34,28 @@ export default class extends Channel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const subCh = this.otherpartyId
|
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
|
||||||
|
|
||||||
|
this.subCh = this.otherpartyId
|
||||||
? `messagingStream:${this.user!.id}-${this.otherpartyId}`
|
? `messagingStream:${this.user!.id}-${this.otherpartyId}`
|
||||||
: `messagingStream:${this.groupId}`;
|
: `messagingStream:${this.groupId}`;
|
||||||
|
|
||||||
// Subscribe messaging stream
|
// Subscribe messaging stream
|
||||||
this.subscriber.on(subCh, data => {
|
this.subscriber.on(this.subCh, this.onEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private onEvent(data: any) {
|
||||||
|
if (data.type === 'typing') {
|
||||||
|
const id = data.body;
|
||||||
|
const begin = this.typers[id] == null;
|
||||||
|
this.typers[id] = new Date();
|
||||||
|
if (begin) {
|
||||||
|
this.emitTypers();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
this.send(data);
|
this.send(data);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
@ -60,4 +77,28 @@ export default class extends Channel {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private async emitTypers() {
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
// Remove not typing users
|
||||||
|
for (const [userId, date] of Object.entries(this.typers)) {
|
||||||
|
if (now.getTime() - date.getTime() > 5000) delete this.typers[userId];
|
||||||
|
}
|
||||||
|
|
||||||
|
const users = await Users.packMany(Object.keys(this.typers), null, { detail: false });
|
||||||
|
|
||||||
|
this.send({
|
||||||
|
type: 'typers',
|
||||||
|
body: users,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
public dispose() {
|
||||||
|
this.subscriber.off(this.subCh, this.onEvent);
|
||||||
|
|
||||||
|
clearInterval(this.emitTypersIntervalId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import { Users, Followings, Mutings, UserProfiles, ChannelFollowings } from '../
|
||||||
import { ApiError } from '../error';
|
import { ApiError } from '../error';
|
||||||
import { AccessToken } from '../../../models/entities/access-token';
|
import { AccessToken } from '../../../models/entities/access-token';
|
||||||
import { UserProfile } from '../../../models/entities/user-profile';
|
import { UserProfile } from '../../../models/entities/user-profile';
|
||||||
|
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '../../../services/stream';
|
||||||
|
import { UserGroup } from '../../../models/entities/user-group';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main stream connection
|
* Main stream connection
|
||||||
|
@ -27,10 +29,10 @@ export default class Connection {
|
||||||
public subscriber: EventEmitter;
|
public subscriber: EventEmitter;
|
||||||
private channels: Channel[] = [];
|
private channels: Channel[] = [];
|
||||||
private subscribingNotes: any = {};
|
private subscribingNotes: any = {};
|
||||||
private followingClock: NodeJS.Timer;
|
private followingClock: ReturnType<typeof setInterval>;
|
||||||
private mutingClock: NodeJS.Timer;
|
private mutingClock: ReturnType<typeof setInterval>;
|
||||||
private followingChannelsClock: NodeJS.Timer;
|
private followingChannelsClock: ReturnType<typeof setInterval>;
|
||||||
private userProfileClock: NodeJS.Timer;
|
private userProfileClock: ReturnType<typeof setInterval>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
wsConnection: websocket.connection,
|
wsConnection: websocket.connection,
|
||||||
|
@ -93,6 +95,12 @@ export default class Connection {
|
||||||
case 'disconnect': this.onChannelDisconnectRequested(body); break;
|
case 'disconnect': this.onChannelDisconnectRequested(body); break;
|
||||||
case 'channel': this.onChannelMessageRequested(body); break;
|
case 'channel': this.onChannelMessageRequested(body); break;
|
||||||
case 'ch': this.onChannelMessageRequested(body); break; // alias
|
case 'ch': this.onChannelMessageRequested(body); break; // alias
|
||||||
|
|
||||||
|
// 個々のチャンネルではなくルートレベルでこれらのメッセージを受け取る理由は、
|
||||||
|
// クライアントの事情を考慮したとき、入力フォームはノートチャンネルやメッセージのメインコンポーネントとは別
|
||||||
|
// なこともあるため、それらのコンポーネントがそれぞれ各チャンネルに接続するようにするのは面倒なため。
|
||||||
|
case 'typingOnChannel': this.typingOnChannel(body.channel); break;
|
||||||
|
case 'typingOnMessaging': this.typingOnMessaging(body); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +266,24 @@ export default class Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private typingOnChannel(channel: ChannelModel['id']) {
|
||||||
|
if (this.user) {
|
||||||
|
publishChannelStream(channel, 'typing', this.user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
|
private typingOnMessaging(param: { partner?: User['id']; group?: UserGroup['id']; }) {
|
||||||
|
if (this.user) {
|
||||||
|
if (param.partner) {
|
||||||
|
publishMessagingStream(param.partner, this.user.id, 'typing', this.user.id);
|
||||||
|
} else if (param.group) {
|
||||||
|
publishGroupMessagingStream(param.group, 'typing', this.user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
private async updateFollowing() {
|
private async updateFollowing() {
|
||||||
const followings = await Followings.find({
|
const followings = await Followings.find({
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
window.onerror = (e) => {
|
||||||
|
document.documentElement.innerHTML = '問題が発生しました。';
|
||||||
|
};
|
||||||
|
|
||||||
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
||||||
(async () => {
|
(async () => {
|
||||||
const v = localStorage.getItem('v') || VERSION;
|
const v = localStorage.getItem('v') || VERSION;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ReversiGame } from '../models/entities/games/reversi/game';
|
||||||
import { UserGroup } from '../models/entities/user-group';
|
import { UserGroup } from '../models/entities/user-group';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import { Antenna } from '../models/entities/antenna';
|
import { Antenna } from '../models/entities/antenna';
|
||||||
|
import { Channel } from '../models/entities/channel';
|
||||||
|
|
||||||
class Publisher {
|
class Publisher {
|
||||||
private publish = (channel: string, type: string | null, value?: any): void => {
|
private publish = (channel: string, type: string | null, value?: any): void => {
|
||||||
|
@ -38,6 +39,10 @@ class Publisher {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public publishChannelStream = (channelId: Channel['id'], type: string, value?: any): void => {
|
||||||
|
this.publish(`channelStream:${channelId}`, type, typeof value === 'undefined' ? null : value);
|
||||||
|
}
|
||||||
|
|
||||||
public publishUserListStream = (listId: UserList['id'], type: string, value?: any): void => {
|
public publishUserListStream = (listId: UserList['id'], type: string, value?: any): void => {
|
||||||
this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value);
|
this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value);
|
||||||
}
|
}
|
||||||
|
@ -84,6 +89,7 @@ export const publishMainStream = publisher.publishMainStream;
|
||||||
export const publishDriveStream = publisher.publishDriveStream;
|
export const publishDriveStream = publisher.publishDriveStream;
|
||||||
export const publishNoteStream = publisher.publishNoteStream;
|
export const publishNoteStream = publisher.publishNoteStream;
|
||||||
export const publishNotesStream = publisher.publishNotesStream;
|
export const publishNotesStream = publisher.publishNotesStream;
|
||||||
|
export const publishChannelStream = publisher.publishChannelStream;
|
||||||
export const publishUserListStream = publisher.publishUserListStream;
|
export const publishUserListStream = publisher.publishUserListStream;
|
||||||
export const publishAntennaStream = publisher.publishAntennaStream;
|
export const publishAntennaStream = publisher.publishAntennaStream;
|
||||||
export const publishMessagingStream = publisher.publishMessagingStream;
|
export const publishMessagingStream = publisher.publishMessagingStream;
|
||||||
|
|
199
yarn.lock
199
yarn.lock
|
@ -2,6 +2,13 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@babel/code-frame@7.12.11":
|
||||||
|
version "7.12.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
|
||||||
|
integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/highlight" "^7.10.4"
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0":
|
"@babel/code-frame@^7.0.0":
|
||||||
version "7.8.3"
|
version "7.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
||||||
|
@ -36,6 +43,15 @@
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80"
|
||||||
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==
|
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==
|
||||||
|
|
||||||
|
"@babel/highlight@^7.10.4":
|
||||||
|
version "7.12.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c"
|
||||||
|
integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-validator-identifier" "^7.12.11"
|
||||||
|
chalk "^2.0.0"
|
||||||
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
"@babel/highlight@^7.8.3":
|
"@babel/highlight@^7.8.3":
|
||||||
version "7.9.0"
|
version "7.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
|
||||||
|
@ -587,10 +603,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
||||||
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
|
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
|
||||||
|
|
||||||
"@types/jsonld@1.5.2":
|
"@types/jsonld@1.5.3":
|
||||||
version "1.5.2"
|
version "1.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/jsonld/-/jsonld-1.5.2.tgz#6de5589f72a73be07f2d0a99a39337f4c4518a78"
|
resolved "https://registry.yarnpkg.com/@types/jsonld/-/jsonld-1.5.3.tgz#5bef463655522eef0530db0011bdc119573b759b"
|
||||||
integrity sha512-e6mgulD3RB3lrjGN6Vvu3ixpRSZ2Qwvsm0oSQIuHsAQUvRklrqnmvKNNyXcQTh/PbB+TrHVVmdLHeYFCH52QnA==
|
integrity sha512-xDjKgwTBOrdevh46a6dota4Lusrn0R6lC1EKEQkBhTrOx4xzGpQKZ/JsXPx7NP2N9qVj7AYo6k5ubWtXAYJkLw==
|
||||||
|
|
||||||
"@types/katex@0.11.0":
|
"@types/katex@0.11.0":
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
|
@ -679,10 +695,10 @@
|
||||||
"@types/koa-compose" "*"
|
"@types/koa-compose" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/koa@2.11.7":
|
"@types/koa@2.13.0":
|
||||||
version "2.11.7"
|
version "2.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.11.7.tgz#3b38f3b9faa66315a84890a771d166fb36463100"
|
resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.0.tgz#6356c48521c0941103b6fcfb97bb01426a99d56d"
|
||||||
integrity sha512-1iXJZZWCePoMe9LGSIPWsu5k5RI4ooXijW78c+nljMn3YbUts8PXoEESu1OeFmrazLPl1l97vTxzwvmH32TWVQ==
|
integrity sha512-hNs1Z2lX+R5sZroIy/WIGbPlH/719s/Nd5uIjSIAdHn9q+g7z6mxOnhwMjK1urE4/NUP0SOoYUOD4MnvD9FRNw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/accepts" "*"
|
"@types/accepts" "*"
|
||||||
"@types/content-disposition" "*"
|
"@types/content-disposition" "*"
|
||||||
|
@ -748,10 +764,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||||
|
|
||||||
"@types/mocha@8.2.0":
|
"@types/mocha@8.2.1":
|
||||||
version "8.2.0"
|
version "8.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
|
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.1.tgz#f3f3ae4590c5386fc7c543aae9b78d4cf30ffee9"
|
||||||
integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
|
integrity sha512-NysN+bNqj6E0Hv4CTGWSlPzMW6vTKjDpOteycDkV4IWBsO+PU48JonrPzV9ODjiI2XrjmA05KInLgF5ivZ/YGQ==
|
||||||
|
|
||||||
"@types/node-fetch@2.5.8":
|
"@types/node-fetch@2.5.8":
|
||||||
version "2.5.8"
|
version "2.5.8"
|
||||||
|
@ -766,10 +782,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.13.tgz#9e425079799322113ae8477297ae6ef51b8e0cdf"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.13.tgz#9e425079799322113ae8477297ae6ef51b8e0cdf"
|
||||||
integrity sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==
|
integrity sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==
|
||||||
|
|
||||||
"@types/node@14.14.25":
|
"@types/node@14.14.31":
|
||||||
version "14.14.25"
|
version "14.14.31"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
|
||||||
integrity sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==
|
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
|
||||||
|
|
||||||
"@types/nodemailer@6.4.0":
|
"@types/nodemailer@6.4.0":
|
||||||
version "6.4.0"
|
version "6.4.0"
|
||||||
|
@ -1531,10 +1547,10 @@ anymatch@~3.1.1:
|
||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
apexcharts@3.24.0:
|
apexcharts@3.25.0:
|
||||||
version "3.24.0"
|
version "3.25.0"
|
||||||
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.24.0.tgz#0fc513e940448524ae9702d39ec287567522d1eb"
|
resolved "https://registry.yarnpkg.com/apexcharts/-/apexcharts-3.25.0.tgz#f3f0f9f344f997230f5c7f2918408aa072627496"
|
||||||
integrity sha512-iT6czJCIVrmAtrcO90MZTQCvC+xi6R6Acf0jNH/d40FVTtCfcqECuKIh5iAMyOTtgUb7+fQ8rbadH2bm1kbL9Q==
|
integrity sha512-uM7OF+jLL4ba79noYcrMwMgJW8DI+Ff28CCQoGq23g25z8nGSQEoU+u12YWlECA9gBA5tbmdaQhMxjlK+M6B9Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
svg.draggable.js "^2.2.2"
|
svg.draggable.js "^2.2.2"
|
||||||
svg.easing.js "^2.0.0"
|
svg.easing.js "^2.0.0"
|
||||||
|
@ -1790,10 +1806,10 @@ autwh@0.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
oauth "0.9.15"
|
oauth "0.9.15"
|
||||||
|
|
||||||
aws-sdk@2.840.0:
|
aws-sdk@2.848.0:
|
||||||
version "2.840.0"
|
version "2.848.0"
|
||||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.840.0.tgz#f5529c9bd3bf0be7f8e855a23ff9c12b1705418f"
|
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.848.0.tgz#5e7706ddd30a55a2d5a5b64c29682a757607ee64"
|
||||||
integrity sha512-ngesHJqb0PXYjJNnCsAX4yLkR6JFQJB+3eDGwh3mYRjcq9voix5RfbCFQT1lwWu7bcMBPCrRIA2lJkkTMYXq+A==
|
integrity sha512-c/e5kaEFl+9aYkrYDkmu5mSZlL+EfP6DnBOMD06fH12gIsaFSMBGtbsDTHABhvSu++LxeI1dJAD148O17MuZvg==
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer "4.9.2"
|
buffer "4.9.2"
|
||||||
events "1.1.1"
|
events "1.1.1"
|
||||||
|
@ -1885,11 +1901,6 @@ big.js@^5.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
|
||||||
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
|
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
|
||||||
|
|
||||||
bignumber.js@^9.0.1:
|
|
||||||
version "9.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
|
|
||||||
integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
|
|
||||||
|
|
||||||
binary-extensions@^2.0.0:
|
binary-extensions@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
||||||
|
@ -2240,13 +2251,12 @@ caseless@~0.12.0:
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||||
|
|
||||||
cbor@6.0.1:
|
cbor@7.0.1:
|
||||||
version "6.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/cbor/-/cbor-6.0.1.tgz#f559abb1b986f54fb9cb1a6855085847bcc1cd61"
|
resolved "https://registry.yarnpkg.com/cbor/-/cbor-7.0.1.tgz#b939a0ae1ce9bb76338e1d193ab2ccd9a85d55d0"
|
||||||
integrity sha512-gVJ2e/DFInWOriOUqNyrZe5xN8RSK49X7G+pLalz32GwKs1xHNXtrkcbV5K4+Z2X7qJiv6f700PnUEaJoIEPGQ==
|
integrity sha512-+SVEDS4B2x9aat+if8rtUbm8WdxArH2/tVKiSD8eCxy7hnVNlESd4EQQM16EOFrUCvSHECscsvq61N1FPejZtw==
|
||||||
dependencies:
|
dependencies:
|
||||||
bignumber.js "^9.0.1"
|
nofilter "^2.0.0"
|
||||||
nofilter "^1.0.4"
|
|
||||||
|
|
||||||
center-align@^0.1.1:
|
center-align@^0.1.1:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
|
@ -2866,10 +2876,10 @@ copy-to@^2.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5"
|
resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5"
|
||||||
integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=
|
integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=
|
||||||
|
|
||||||
core-js@3.8.3:
|
core-js@3.9.0:
|
||||||
version "3.8.3"
|
version "3.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.3.tgz#c21906e1f14f3689f93abcc6e26883550dd92dd0"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.0.tgz#790b1bb11553a2272b36e2625c7179db345492f8"
|
||||||
integrity sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==
|
integrity sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ==
|
||||||
|
|
||||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
@ -3799,15 +3809,15 @@ escodegen@^1.14.1:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-plugin-vue@7.5.0:
|
eslint-plugin-vue@7.6.0:
|
||||||
version "7.5.0"
|
version "7.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.5.0.tgz#cc6d983eb22781fa2440a7573cf39af439bb5725"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.6.0.tgz#ea616e6dfd45d545adb16cba628c5a992cc31f0b"
|
||||||
integrity sha512-QnMMTcyV8PLxBz7QQNAwISSEs6LYk2LJvGlxalXvpCtfKnqo7qcY0aZTIxPe8QOnHd7WCwiMZLOJzg6A03T0Gw==
|
integrity sha512-qYpKwAvpcQXyUXVcG8Zd+fxHDx9iSgTQuO7dql7Ug/2BCvNNDr6s3I9p8MoUo23JJdO7ZAjW3vSwY/EBf4uBcw==
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-utils "^2.1.0"
|
eslint-utils "^2.1.0"
|
||||||
natural-compare "^1.4.0"
|
natural-compare "^1.4.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
vue-eslint-parser "^7.4.1"
|
vue-eslint-parser "^7.5.0"
|
||||||
|
|
||||||
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
|
@ -3834,12 +3844,12 @@ eslint-visitor-keys@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
|
||||||
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
|
||||||
|
|
||||||
eslint@7.19.0:
|
eslint@7.20.0:
|
||||||
version "7.19.0"
|
version "7.20.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.19.0.tgz#6719621b196b5fad72e43387981314e5d0dc3f41"
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.20.0.tgz#db07c4ca4eda2e2316e7aa57ac7fc91ec550bdc7"
|
||||||
integrity sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==
|
integrity sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/code-frame" "^7.0.0"
|
"@babel/code-frame" "7.12.11"
|
||||||
"@eslint/eslintrc" "^0.3.0"
|
"@eslint/eslintrc" "^0.3.0"
|
||||||
ajv "^6.10.0"
|
ajv "^6.10.0"
|
||||||
chalk "^4.0.0"
|
chalk "^4.0.0"
|
||||||
|
@ -3851,7 +3861,7 @@ eslint@7.19.0:
|
||||||
eslint-utils "^2.1.0"
|
eslint-utils "^2.1.0"
|
||||||
eslint-visitor-keys "^2.0.0"
|
eslint-visitor-keys "^2.0.0"
|
||||||
espree "^7.3.1"
|
espree "^7.3.1"
|
||||||
esquery "^1.2.0"
|
esquery "^1.4.0"
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
file-entry-cache "^6.0.0"
|
file-entry-cache "^6.0.0"
|
||||||
functional-red-black-tree "^1.0.1"
|
functional-red-black-tree "^1.0.1"
|
||||||
|
@ -3905,10 +3915,10 @@ esprima@^4.0.0, esprima@^4.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||||
|
|
||||||
esquery@^1.0.1, esquery@^1.2.0:
|
esquery@^1.4.0:
|
||||||
version "1.3.1"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57"
|
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
|
||||||
integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==
|
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
|
||||||
dependencies:
|
dependencies:
|
||||||
estraverse "^5.1.0"
|
estraverse "^5.1.0"
|
||||||
|
|
||||||
|
@ -5729,10 +5739,10 @@ json5@^2.1.2, json5@^2.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
jsonld@3.3.0:
|
jsonld@4.0.1:
|
||||||
version "3.3.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-3.3.0.tgz#1b03fe1458f9ffc2918fc30e90320343c988d07b"
|
resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-4.0.1.tgz#b8d464ae94bf00b54a219a99782cb488c49842d5"
|
||||||
integrity sha512-0y/rctORxwlezPw/vHp+vbR2qTqHSwt9weZK3RjtDYSzmbGjtQlJZuHduCBfIoXggXPvlnI/2EjYcoyzDD/WRw==
|
integrity sha512-ltEqMQB37ZxZnsgmI+9rqHYkz1M6PqUykuS1t2aQNuH1oiLrUDYz5nyVkHQDgjFd7CFKTIWeLiNhwdwFrH5o5A==
|
||||||
dependencies:
|
dependencies:
|
||||||
canonicalize "^1.0.1"
|
canonicalize "^1.0.1"
|
||||||
lru-cache "^5.1.1"
|
lru-cache "^5.1.1"
|
||||||
|
@ -5740,7 +5750,6 @@ jsonld@3.3.0:
|
||||||
rdf-canonize "^2.0.1"
|
rdf-canonize "^2.0.1"
|
||||||
request "^2.88.0"
|
request "^2.88.0"
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
xmldom "0.1.19"
|
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
jsprim@^1.2.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
|
@ -6827,10 +6836,10 @@ nodemailer@6.4.18:
|
||||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.18.tgz#2788c85792844fc17befda019031609017f4b9a1"
|
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.18.tgz#2788c85792844fc17befda019031609017f4b9a1"
|
||||||
integrity sha512-ht9cXxQ+lTC+t00vkSIpKHIyM4aXIsQ1tcbQCn5IOnxYHi81W2XOaU66EQBFFpbtzLEBTC94gmkbD4mGZQzVpA==
|
integrity sha512-ht9cXxQ+lTC+t00vkSIpKHIyM4aXIsQ1tcbQCn5IOnxYHi81W2XOaU66EQBFFpbtzLEBTC94gmkbD4mGZQzVpA==
|
||||||
|
|
||||||
nofilter@^1.0.4:
|
nofilter@^2.0.0:
|
||||||
version "1.0.4"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e"
|
resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-2.0.0.tgz#57a2d7c6fcd34dd396f490d6942c4f58640b5823"
|
||||||
integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==
|
integrity sha512-i3ck2PUWBa+trsGGBvwS3msnTowbFei5G++BgpOpT7y7VTrprXphMQP5svTdsMLdttKDZFo+5RqVWRqhmf+BwQ==
|
||||||
|
|
||||||
noop-logger@^0.1.1:
|
noop-logger@^0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
|
@ -8157,10 +8166,10 @@ postcss-zindex@^2.0.1:
|
||||||
postcss "^5.0.4"
|
postcss "^5.0.4"
|
||||||
uniqs "^2.0.0"
|
uniqs "^2.0.0"
|
||||||
|
|
||||||
postcss@8.2.5, postcss@^8.2.4:
|
postcss@8.2.6:
|
||||||
version "8.2.5"
|
version "8.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.5.tgz#3c75149ada4e93db9521913654c0144517f77c9a"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe"
|
||||||
integrity sha512-wMcb7BpDcm3gxQOQx46NDNT36Kk0Ao6PJLLI2ed5vehbbbxCEuslSQzbQ2sfSKy+gkYxhWcGWSeaK+gwm4KIZg==
|
integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg==
|
||||||
dependencies:
|
dependencies:
|
||||||
colorette "^1.2.1"
|
colorette "^1.2.1"
|
||||||
nanoid "^3.1.20"
|
nanoid "^3.1.20"
|
||||||
|
@ -8185,6 +8194,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.3
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
supports-color "^6.1.0"
|
supports-color "^6.1.0"
|
||||||
|
|
||||||
|
postcss@^8.2.4:
|
||||||
|
version "8.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.5.tgz#3c75149ada4e93db9521913654c0144517f77c9a"
|
||||||
|
integrity sha512-wMcb7BpDcm3gxQOQx46NDNT36Kk0Ao6PJLLI2ed5vehbbbxCEuslSQzbQ2sfSKy+gkYxhWcGWSeaK+gwm4KIZg==
|
||||||
|
dependencies:
|
||||||
|
colorette "^1.2.1"
|
||||||
|
nanoid "^3.1.20"
|
||||||
|
source-map "^0.6.1"
|
||||||
|
|
||||||
postgres-array@~2.0.0:
|
postgres-array@~2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||||
|
@ -9125,10 +9143,10 @@ sass-loader@11.0.1:
|
||||||
klona "^2.0.4"
|
klona "^2.0.4"
|
||||||
neo-async "^2.6.2"
|
neo-async "^2.6.2"
|
||||||
|
|
||||||
sass@1.32.6:
|
sass@1.32.8:
|
||||||
version "1.32.6"
|
version "1.32.8"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.6.tgz#e3646c8325cd97ff75a8a15226007f3ccd221393"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.8.tgz#f16a9abd8dc530add8834e506878a2808c037bdc"
|
||||||
integrity sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ==
|
integrity sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=2.0.0 <4.0.0"
|
chokidar ">=2.0.0 <4.0.0"
|
||||||
|
|
||||||
|
@ -10249,10 +10267,10 @@ trace-redirect@1.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/trace-redirect/-/trace-redirect-1.0.6.tgz#ac629b5bf8247d30dde5a35fe9811b811075b504"
|
resolved "https://registry.yarnpkg.com/trace-redirect/-/trace-redirect-1.0.6.tgz#ac629b5bf8247d30dde5a35fe9811b811075b504"
|
||||||
integrity sha512-UUfa1DjjU5flcjMdaFIiIEGDTyu2y/IiMjOX4uGXa7meKBS4vD4f2Uy/tken9Qkd4Jsm4sRsfZcIIPqrRVF3Mg==
|
integrity sha512-UUfa1DjjU5flcjMdaFIiIEGDTyu2y/IiMjOX4uGXa7meKBS4vD4f2Uy/tken9Qkd4Jsm4sRsfZcIIPqrRVF3Mg==
|
||||||
|
|
||||||
ts-loader@8.0.16:
|
ts-loader@8.0.17:
|
||||||
version "8.0.16"
|
version "8.0.17"
|
||||||
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.16.tgz#a60311f01f015518e1cfbb5698e6ca8830cd2391"
|
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.17.tgz#98f2ccff9130074f4079fd89b946b4c637b1f2fc"
|
||||||
integrity sha512-Cr9ywsgg1n8cjGjIogHLPlqe3WJUHzuJaqwNo5I596KpIqekKzxvSENbrXeOypHcXSPPsr8hV6mglngyXvcKrg==
|
integrity sha512-OeVfSshx6ot/TCxRwpBHQ/4lRzfgyTkvi7ghDVrLXOHzTbSK413ROgu/xNqM72i3AFeAIJgQy78FwSMKmOW68w==
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^4.1.0"
|
chalk "^4.1.0"
|
||||||
enhanced-resolve "^4.0.0"
|
enhanced-resolve "^4.0.0"
|
||||||
|
@ -10403,10 +10421,10 @@ typedarray@^0.0.6:
|
||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typeorm@0.2.30:
|
typeorm@0.2.31:
|
||||||
version "0.2.30"
|
version "0.2.31"
|
||||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.30.tgz#a0df2256402cbcdde8049a244437560495ce9b38"
|
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.31.tgz#82b8a1b233224f81c738f53b0380386ccf360917"
|
||||||
integrity sha512-qpr8AO3Phi6ZF7qMHOrRdNisVt8jE1KfmW0ooLFcXscA87aJ12aBPyB9cJfxGNjNwd7B3WIK9ZlBveWiqd74QA==
|
integrity sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sqltools/formatter" "1.2.2"
|
"@sqltools/formatter" "1.2.2"
|
||||||
app-root-path "^3.0.0"
|
app-root-path "^3.0.0"
|
||||||
|
@ -10756,16 +10774,16 @@ vue-color@2.8.1:
|
||||||
material-colors "^1.0.0"
|
material-colors "^1.0.0"
|
||||||
tinycolor2 "^1.1.2"
|
tinycolor2 "^1.1.2"
|
||||||
|
|
||||||
vue-eslint-parser@^7.4.1:
|
vue-eslint-parser@^7.5.0:
|
||||||
version "7.4.1"
|
version "7.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.4.1.tgz#e4adcf7876a7379758d9056a72235af18a587f92"
|
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.5.0.tgz#b68221c55fee061899afcfb4441ec74c1495285e"
|
||||||
integrity sha512-AFvhdxpFvliYq1xt/biNBslTHE/zbEvSnr1qfHA/KxRIpErmEDrQZlQnvEexednRHmLfDNOMuDYwZL5xkLzIXQ==
|
integrity sha512-6EHzl00hIpy4yWZo3qSbtvtVw1A1cTKOv1w95QSuAqGgk4113XtRjvNIiEGo49r0YWOPYsrmI4Dl64axL5Agrw==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
eslint-scope "^5.0.0"
|
eslint-scope "^5.0.0"
|
||||||
eslint-visitor-keys "^1.1.0"
|
eslint-visitor-keys "^1.1.0"
|
||||||
espree "^6.2.1"
|
espree "^6.2.1"
|
||||||
esquery "^1.0.1"
|
esquery "^1.4.0"
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
|
|
||||||
vue-json-pretty@1.7.1:
|
vue-json-pretty@1.7.1:
|
||||||
|
@ -10904,10 +10922,10 @@ webpack-sources@^2.1.1:
|
||||||
source-list-map "^2.0.1"
|
source-list-map "^2.0.1"
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
|
|
||||||
webpack@5.21.2:
|
webpack@5.23.0:
|
||||||
version "5.21.2"
|
version "5.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.21.2.tgz#647507e50d3637695be28af58a6a8246050394e7"
|
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.23.0.tgz#9ed57e9a54b267b3549899271ad780cddc6ee316"
|
||||||
integrity sha512-xHflCenx+AM4uWKX71SWHhxml5aMXdy2tu/vdi4lClm7PADKxlyDAFFN1rEFzNV0MAoPpHtBeJnl/+K6F4QBPg==
|
integrity sha512-RC6dwDuRxiU75F8XC4H08NtzUrMfufw5LDnO8dTtaKU2+fszEdySCgZhNwSBBn516iNaJbQI7T7OPHIgCwcJmg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/eslint-scope" "^3.7.0"
|
"@types/eslint-scope" "^3.7.0"
|
||||||
"@types/estree" "^0.0.46"
|
"@types/estree" "^0.0.46"
|
||||||
|
@ -11150,11 +11168,6 @@ xmlchars@^2.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
|
||||||
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
|
||||||
|
|
||||||
xmldom@0.1.19:
|
|
||||||
version "0.1.19"
|
|
||||||
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.19.tgz#631fc07776efd84118bf25171b37ed4d075a0abc"
|
|
||||||
integrity sha1-Yx/Ad3bv2EEYvyUXGzftTQdaCrw=
|
|
||||||
|
|
||||||
xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
|
xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
|
||||||
version "4.0.2"
|
version "4.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||||
|
|
Loading…
Reference in a new issue