Compare commits
8 Commits
d5e349ee88
...
62ee2ef01f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62ee2ef01f | ||
|
|
04125a1495 | ||
|
|
110a90ed7a | ||
|
|
bfc14777be | ||
|
|
4e34e70a11 | ||
|
|
2d2bc7be83 | ||
|
|
5d6c4d6660 | ||
|
|
ab8895b008 |
@@ -7,6 +7,7 @@ export type CallMethod =
|
|||||||
"User.setAvatar" |
|
"User.setAvatar" |
|
||||||
"User.updateProfile" |
|
"User.updateProfile" |
|
||||||
"User.getMyInfo" |
|
"User.getMyInfo" |
|
||||||
|
"User.resetPassword" |
|
||||||
|
|
||||||
"User.getInfo" |
|
"User.getInfo" |
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { CallMethod, ClientEvent, CallableMethodBeforeAuth } from './ApiDeclare.
|
|||||||
import ApiCallbackMessage from './ApiCallbackMessage.ts'
|
import ApiCallbackMessage from './ApiCallbackMessage.ts'
|
||||||
import User from "./client_data/User.ts"
|
import User from "./client_data/User.ts"
|
||||||
import data from "../Data.ts"
|
import data from "../Data.ts"
|
||||||
import { checkApiSuccessOrSncakbar } from "../ui/snackbar.ts"
|
import { checkApiSuccessOrSncakbar, snackbar } from "../ui/snackbar.ts"
|
||||||
import randomUUID from "../randomUUID.ts"
|
import randomUUID from "../randomUUID.ts"
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
@@ -32,6 +32,21 @@ class Client {
|
|||||||
})
|
})
|
||||||
this.socket!.on("disconnect", () => {
|
this.socket!.on("disconnect", () => {
|
||||||
this.connected = false
|
this.connected = false
|
||||||
|
const s = snackbar({
|
||||||
|
message: '重新连接服务器中...',
|
||||||
|
placement: 'top',
|
||||||
|
autoCloseDelay: 0,
|
||||||
|
})
|
||||||
|
let i = 1
|
||||||
|
const id = setInterval(() => {
|
||||||
|
s.textContent = `重新连接服务器中... (${i}s)`
|
||||||
|
i++
|
||||||
|
this.socket!.connect()
|
||||||
|
}, 1000)
|
||||||
|
this.socket!.once('connect', () => {
|
||||||
|
s.open = false
|
||||||
|
clearTimeout(id)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
this.socket!.on("The_White_Silk", (name: string, data: unknown, callback: (ret: unknown) => void) => {
|
this.socket!.on("The_White_Silk", (name: string, data: unknown, callback: (ret: unknown) => void) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
tabRef.current != null && setTabItemSelected(tabRef.current!.value as string)
|
tabRef.current != null && setTabItemSelected(tabRef.current!.value as string)
|
||||||
})
|
})
|
||||||
|
|
||||||
useAsyncEffect(async () => {
|
async function getChatInfoAndInit() {
|
||||||
|
setMessagesList([])
|
||||||
|
page.current = 0
|
||||||
const re = await Client.invoke('Chat.getInfo', {
|
const re = await Client.invoke('Chat.getInfo', {
|
||||||
token: data.access_token,
|
token: data.access_token,
|
||||||
target: target,
|
target: target,
|
||||||
@@ -101,7 +103,8 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
})
|
})
|
||||||
}, 300)
|
}, 300)
|
||||||
}, [target])
|
}
|
||||||
|
useAsyncEffect(getChatInfoAndInit, [target])
|
||||||
|
|
||||||
const page = React.useRef(0)
|
const page = React.useRef(0)
|
||||||
async function loadMore() {
|
async function loadMore() {
|
||||||
@@ -222,6 +225,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
addFile(file.type, file.name, file)
|
addFile(file.type, file.name, file)
|
||||||
}
|
}
|
||||||
|
uploadChatAvatarRef.current!.value = ''
|
||||||
})
|
})
|
||||||
useEventListener(uploadChatAvatarRef, 'change', async (_e) => {
|
useEventListener(uploadChatAvatarRef, 'change', async (_e) => {
|
||||||
const file = uploadChatAvatarRef.current!.files?.[0] as File
|
const file = uploadChatAvatarRef.current!.files?.[0] as File
|
||||||
@@ -232,6 +236,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
target: target,
|
target: target,
|
||||||
avatar: file
|
avatar: file
|
||||||
})
|
})
|
||||||
|
uploadChatAvatarRef.current!.value = ''
|
||||||
|
|
||||||
if (checkApiSuccessOrSncakbar(re, "修改失败")) return
|
if (checkApiSuccessOrSncakbar(re, "修改失败")) return
|
||||||
snackbar({
|
snackbar({
|
||||||
@@ -283,6 +288,11 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
<div style={{
|
<div style={{
|
||||||
flexGrow: '1',
|
flexGrow: '1',
|
||||||
}}></div>
|
}}></div>
|
||||||
|
<mdui-button-icon icon="refresh" onClick={() => getChatInfoAndInit()} style={{
|
||||||
|
alignSelf: 'center',
|
||||||
|
marginLeft: '5px',
|
||||||
|
marginRight: '5px',
|
||||||
|
}}></mdui-button-icon>
|
||||||
<mdui-button-icon icon="info" onClick={() => openChatInfoDialog(chatInfo)} style={{
|
<mdui-button-icon icon="info" onClick={() => openChatInfoDialog(chatInfo)} style={{
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
marginLeft: '5px',
|
marginLeft: '5px',
|
||||||
@@ -297,7 +307,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}}>
|
}}>
|
||||||
<div>
|
<div>
|
||||||
<mdui-button onClick={async () => {
|
<mdui-button disabled={!groupPreferenceStore.state.allow_new_member_join} onClick={async () => {
|
||||||
const re = await Client.invoke("Chat.sendJoinRequest", {
|
const re = await Client.invoke("Chat.sendJoinRequest", {
|
||||||
token: data.access_token,
|
token: data.access_token,
|
||||||
target: target,
|
target: target,
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ export default function MyProfileDialog({
|
|||||||
}}></mdui-divider>
|
}}></mdui-divider>
|
||||||
|
|
||||||
<mdui-list>
|
<mdui-list>
|
||||||
<mdui-list-item icon="edit" rounded onClick={() => userProfileEditDialogRef.current!.open = true}>編輯資料</mdui-list-item>
|
<mdui-list-item icon="edit" rounded onClick={() => userProfileEditDialogRef.current!.open = true}>编辑资料</mdui-list-item>
|
||||||
|
<mdui-list-item icon="settings" rounded>账号设定</mdui-list-item>
|
||||||
{/*
|
{/*
|
||||||
<mdui-list-item icon="settings" rounded>賬號設定</mdui-list-item>
|
|
||||||
<mdui-list-item icon="lock" rounded>隱私設定</mdui-list-item>
|
<mdui-list-item icon="lock" rounded>隱私設定</mdui-list-item>
|
||||||
*/}
|
*/}
|
||||||
<mdui-divider style={{
|
<mdui-divider style={{
|
||||||
@@ -87,6 +87,7 @@ export default function MyProfileDialog({
|
|||||||
{
|
{
|
||||||
text: "确定",
|
text: "确定",
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
|
data.refresh_token = ''
|
||||||
data.access_token = ''
|
data.access_token = ''
|
||||||
data.apply()
|
data.apply()
|
||||||
location.reload()
|
location.reload()
|
||||||
@@ -97,6 +98,13 @@ export default function MyProfileDialog({
|
|||||||
})}>退出登录</mdui-list-item>
|
})}>退出登录</mdui-list-item>
|
||||||
</mdui-list>
|
</mdui-list>
|
||||||
</mdui-dialog>
|
</mdui-dialog>
|
||||||
|
{
|
||||||
|
// 账号设定
|
||||||
|
}
|
||||||
|
<mdui-dialog close-on-overlay-click close-on-esc ref={userProfileEditDialogRef} headline="账号设定">
|
||||||
|
|
||||||
|
<mdui-button slot="action" variant="text" onClick={() => userProfileEditDialogRef.current!.open = false}>关闭</mdui-button>
|
||||||
|
</mdui-dialog>
|
||||||
{
|
{
|
||||||
// 個人資料編輯
|
// 個人資料編輯
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export type CallMethod =
|
|||||||
"User.setAvatar" |
|
"User.setAvatar" |
|
||||||
"User.updateProfile" |
|
"User.updateProfile" |
|
||||||
"User.getMyInfo" |
|
"User.getMyInfo" |
|
||||||
|
"User.resetPassword" |
|
||||||
|
|
||||||
"User.getInfo" |
|
"User.getInfo" |
|
||||||
|
|
||||||
|
|||||||
@@ -283,8 +283,16 @@ export default class ChatApi extends BaseApi {
|
|||||||
code: 404,
|
code: 404,
|
||||||
msg: "对话不存在",
|
msg: "对话不存在",
|
||||||
}
|
}
|
||||||
|
if (chat.bean.type == 'group') {
|
||||||
chat.addJoinRequest(token.author, args.reason as string)
|
const settings = ChatGroup.fromChat(chat).getSettings()
|
||||||
|
if (settings.settings.allow_new_member_join)
|
||||||
|
chat.addJoinRequest(token.author, args.reason as string)
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
code: 403,
|
||||||
|
msg: "该对话不允许加入请求",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code: 200,
|
code: 200,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default class UserApi extends BaseApi {
|
|||||||
msg: "验证失败",
|
msg: "验证失败",
|
||||||
code: 401,
|
code: 401,
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = User.findById(refresh_token.author) as User
|
const user = User.findById(refresh_token.author) as User
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -156,6 +156,41 @@ export default class UserApi extends BaseApi {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// 登錄
|
||||||
|
this.registerEvent("User.resetPassword", (args, { deviceId }) => {
|
||||||
|
if (this.checkArgsMissing(args, ['token', 'old_password', 'new_password'])) return {
|
||||||
|
msg: "参数缺失",
|
||||||
|
code: 400,
|
||||||
|
}
|
||||||
|
if (this.checkArgsEmpty(args, ['token', 'old_password', 'new_password'])) return {
|
||||||
|
msg: "参数不得为空",
|
||||||
|
code: 400,
|
||||||
|
}
|
||||||
|
|
||||||
|
const token = TokenManager.decode(args.token as string)
|
||||||
|
if (!this.checkToken(token, deviceId)) return {
|
||||||
|
code: 401,
|
||||||
|
msg: "令牌无效",
|
||||||
|
}
|
||||||
|
const user = User.findById(token.author) as User
|
||||||
|
|
||||||
|
if (user.getPassword() == args.old_password) {
|
||||||
|
user.setPassword(args.new_password as string)
|
||||||
|
return {
|
||||||
|
msg: "成功",
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
refresh_token: TokenManager.make(user, null, deviceId, 'refresh_token'),
|
||||||
|
access_token: TokenManager.make(user, null, deviceId),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: "账号或密码错误",
|
||||||
|
code: 400,
|
||||||
|
}
|
||||||
|
})
|
||||||
/*
|
/*
|
||||||
* ================================================
|
* ================================================
|
||||||
* 個人資料
|
* 個人資料
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export default class Chat {
|
|||||||
return Chat.database.prepare(`SELECT * FROM ${this.getJoinRequestsTableName()}`).all()
|
return Chat.database.prepare(`SELECT * FROM ${this.getJoinRequestsTableName()}`).all()
|
||||||
}
|
}
|
||||||
protected findAllJoinRequestsByCondition(condition: string, ...args: SQLInputValue[]) {
|
protected findAllJoinRequestsByCondition(condition: string, ...args: SQLInputValue[]) {
|
||||||
return Chat.database.prepare(`SELECT * FROM ${this.getAdminsTableName()} WHERE ${condition}`).all(...args)
|
return Chat.database.prepare(`SELECT * FROM ${this.getJoinRequestsTableName()} WHERE ${condition}`).all(...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user