Compare commits
4 Commits
f9dfa466f0
...
4b9d78d0d5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b9d78d0d5 | ||
|
|
1f6f8a768f | ||
|
|
a7c61d9306 | ||
|
|
0247eaeda9 |
@@ -1,4 +1,4 @@
|
|||||||
import { Tab, TextField } from "mdui"
|
import { Tab, Tabs, TextField } from "mdui"
|
||||||
import { $ } from "mdui/jq"
|
import { $ } from "mdui/jq"
|
||||||
import useEventListener from "../useEventListener.ts"
|
import useEventListener from "../useEventListener.ts"
|
||||||
import Element_Message from "./Message.tsx"
|
import Element_Message from "./Message.tsx"
|
||||||
@@ -31,6 +31,7 @@ import JoinRequestsList from "./JoinRequestsList.tsx"
|
|||||||
import getUrlForFileByHash from "../../getUrlForFileByHash.ts"
|
import getUrlForFileByHash from "../../getUrlForFileByHash.ts"
|
||||||
import escapeHTML from "../../escapeHtml.ts"
|
import escapeHTML from "../../escapeHtml.ts"
|
||||||
import GroupMembersList from "./GroupMembersList.tsx"
|
import GroupMembersList from "./GroupMembersList.tsx"
|
||||||
|
import isMobileUI from "../isMobileUI.ts"
|
||||||
|
|
||||||
interface Args extends React.HTMLAttributes<HTMLElement> {
|
interface Args extends React.HTMLAttributes<HTMLElement> {
|
||||||
target: string
|
target: string
|
||||||
@@ -95,6 +96,18 @@ const markedInstance = new marked.Marked({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
interface MduiTabFitSizeArgs extends React.HTMLAttributes<HTMLElement & Tab> {
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
function MduiTabFitSize({ children, ...props }: MduiTabFitSizeArgs) {
|
||||||
|
return <mdui-tab {...props} style={{
|
||||||
|
...props?.style,
|
||||||
|
minWidth: 'fit-content',
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</mdui-tab>
|
||||||
|
}
|
||||||
|
|
||||||
export default function ChatFragment({ target, showReturnButton, onReturnButtonClicked, openChatInfoDialog, openUserInfoDialog, ...props }: Args) {
|
export default function ChatFragment({ target, showReturnButton, onReturnButtonClicked, openChatInfoDialog, openUserInfoDialog, ...props }: Args) {
|
||||||
const [messagesList, setMessagesList] = React.useState([] as Message[])
|
const [messagesList, setMessagesList] = React.useState([] as Message[])
|
||||||
const [chatInfo, setChatInfo] = React.useState({
|
const [chatInfo, setChatInfo] = React.useState({
|
||||||
@@ -114,6 +127,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
$(containerTabRef.current!.shadowRoot).append(`<style>.container::after { height: 0 !important; }</style>`)
|
$(containerTabRef.current!.shadowRoot).append(`<style>.container::after { height: 0 !important; }</style>`)
|
||||||
$(tabRef.current!.shadowRoot).append(`<style>.container::after { height: 0 !important; }</style>`)
|
$(tabRef.current!.shadowRoot).append(`<style>.container::after { height: 0 !important; }</style>`)
|
||||||
|
; (!isMobileUI()) && $(tabRef.current!.shadowRoot).append(`<style>.no-scroll-bar::-webkit-scrollbar{width:0px !important}*::-webkit-scrollbar{width:7px;height:10px}*::-webkit-scrollbar-track{width:6px;background:rgba(#101f1c,0.1);-webkit-border-radius:2em;-moz-border-radius:2em;border-radius:2em}*::-webkit-scrollbar-thumb{background-color:rgba(144,147,153,0.5);background-clip:padding-box;min-height:28px;-webkit-border-radius:2em;-moz-border-radius:2em;border-radius:2em;transition:background-color 0.3s;cursor:pointer}*::-webkit-scrollbar-thumb:hover{background-color:rgba(144,147,153,0.3)}</style>`)
|
||||||
}, [target])
|
}, [target])
|
||||||
|
|
||||||
async function getChatInfoAndInit() {
|
async function getChatInfoAndInit() {
|
||||||
@@ -347,17 +361,18 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
overflowX: 'auto',
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
chatInfo.is_member ? <>
|
chatInfo.is_member ? <>
|
||||||
<mdui-tab value="Chat">{chatInfo.title}</mdui-tab>
|
<MduiTabFitSize value="Chat">{chatInfo.title}</MduiTabFitSize>
|
||||||
{chatInfo.type == 'group' && chatInfo.is_admin && <mdui-tab value="NewMemberRequests">加入请求</mdui-tab>}
|
{chatInfo.type == 'group' && chatInfo.is_admin && <MduiTabFitSize value="NewMemberRequests">加入请求</MduiTabFitSize>}
|
||||||
{chatInfo.type == 'group' && <mdui-tab value="GroupMembers">群组成员</mdui-tab>}
|
{chatInfo.type == 'group' && <MduiTabFitSize value="GroupMembers">群组成员</MduiTabFitSize>}
|
||||||
</>
|
</>
|
||||||
: <mdui-tab value="RequestJoin">{chatInfo.title}</mdui-tab>
|
: <MduiTabFitSize value="RequestJoin">{chatInfo.title}</MduiTabFitSize>
|
||||||
}
|
}
|
||||||
{chatInfo.type == 'group' && <mdui-tab value="Settings">设置</mdui-tab>}
|
{chatInfo.type == 'group' && <MduiTabFitSize value="Settings">设置</MduiTabFitSize>}
|
||||||
<mdui-tab value="None" style={{ display: 'none' }}></mdui-tab>
|
<MduiTabFitSize value="None" style={{ display: 'none' }}></MduiTabFitSize>
|
||||||
</mdui-tabs>
|
</mdui-tabs>
|
||||||
<div style={{
|
<div style={{
|
||||||
flexGrow: '1',
|
flexGrow: '1',
|
||||||
@@ -441,9 +456,20 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
{
|
{
|
||||||
(() => {
|
(() => {
|
||||||
let date = new Date(0)
|
let date = new Date(0)
|
||||||
|
let user: string
|
||||||
|
function timeAddZeroPrefix(t: number) {
|
||||||
|
if (t >= 0 && t < 10)
|
||||||
|
return '0' + t
|
||||||
|
return t + ''
|
||||||
|
}
|
||||||
return messagesList.map((msg) => {
|
return messagesList.map((msg) => {
|
||||||
const lastDate = date
|
const lastDate = date
|
||||||
|
const lastUser = user
|
||||||
date = new Date(msg.time)
|
date = new Date(msg.time)
|
||||||
|
user = msg.user_id
|
||||||
|
|
||||||
|
const shouldShowTime = msg.user_id != null &&
|
||||||
|
(date.getMinutes() != lastDate.getMinutes() || date.getDate() != lastDate.getDate() || date.getMonth() != lastDate.getMonth() || date.getFullYear() != lastDate.getFullYear())
|
||||||
|
|
||||||
const msgElement = msg.user_id == null ? <SystemMessage><div dangerouslySetInnerHTML={{
|
const msgElement = msg.user_id == null ? <SystemMessage><div dangerouslySetInnerHTML={{
|
||||||
__html: DOMPurify.sanitize(markedInstance.parse(msg.text) as string, {
|
__html: DOMPurify.sanitize(markedInstance.parse(msg.text) as string, {
|
||||||
@@ -455,6 +481,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
}} /></SystemMessage> : <Element_Message
|
}} /></SystemMessage> : <Element_Message
|
||||||
|
noUserDisplay={lastUser == user && !shouldShowTime}
|
||||||
rawData={msg.text}
|
rawData={msg.text}
|
||||||
renderHTML={DOMPurify.sanitize(markedInstance.parse(msg.text) as string, sanitizeConfig)}
|
renderHTML={DOMPurify.sanitize(markedInstance.parse(msg.text) as string, sanitizeConfig)}
|
||||||
message={msg}
|
message={msg}
|
||||||
@@ -467,18 +494,18 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
msg.user_id != null &&
|
shouldShowTime
|
||||||
(date.getMinutes() != lastDate.getMinutes() || date.getDate() != lastDate.getDate() || date.getMonth() != lastDate.getMonth() || date.getFullYear() != lastDate.getFullYear())
|
|
||||||
&& <mdui-tooltip content={`${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`}>
|
&& <mdui-tooltip content={`${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`}>
|
||||||
<div style={{
|
<div style={{
|
||||||
fontSize: '87%',
|
fontSize: '87%',
|
||||||
marginTop: '10px',
|
marginTop: '13px',
|
||||||
|
marginBottom: '10px',
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
(date.getFullYear() != lastDate.getFullYear() ? `${date.getFullYear()}年` : '')
|
(date.getFullYear() != lastDate.getFullYear() ? `${date.getFullYear()}年` : '')
|
||||||
+ `${date.getMonth() + 1}月`
|
+ `${date.getMonth() + 1}月`
|
||||||
+ `${date.getDate()}日`
|
+ `${date.getDate()}日`
|
||||||
+ ` ${date.getHours()}:${date.getMinutes()}`
|
+ ` ${timeAddZeroPrefix(date.getHours())}:${timeAddZeroPrefix(date.getMinutes())}`
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</mdui-tooltip>
|
</mdui-tooltip>
|
||||||
|
|||||||
@@ -13,14 +13,6 @@ import User from "../../api/client_data/User.ts"
|
|||||||
import getUrlForFileByHash from "../../getUrlForFileByHash.ts"
|
import getUrlForFileByHash from "../../getUrlForFileByHash.ts"
|
||||||
import escapeHTML from "../../escapeHtml.ts"
|
import escapeHTML from "../../escapeHtml.ts"
|
||||||
|
|
||||||
interface Args extends React.HTMLAttributes<HTMLElement> {
|
|
||||||
userId: string
|
|
||||||
rawData: string
|
|
||||||
renderHTML: string
|
|
||||||
message: Data_Message
|
|
||||||
openUserInfoDialog: (user: User | string) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
function prettyFlatParsedMessage(html: string) {
|
function prettyFlatParsedMessage(html: string) {
|
||||||
const elements = new DOMParser().parseFromString(html, 'text/html').body.children
|
const elements = new DOMParser().parseFromString(html, 'text/html').body.children
|
||||||
// 纯文本直接处理
|
// 纯文本直接处理
|
||||||
@@ -72,7 +64,16 @@ function prettyFlatParsedMessage(html: string) {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Message({ userId, rawData, renderHTML, message, openUserInfoDialog, ...props }: Args) {
|
interface Args extends React.HTMLAttributes<HTMLElement> {
|
||||||
|
userId: string
|
||||||
|
noUserDisplay?: boolean
|
||||||
|
rawData: string
|
||||||
|
renderHTML: string
|
||||||
|
message: Data_Message
|
||||||
|
openUserInfoDialog: (user: User | string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Message({ userId, rawData, renderHTML, message, openUserInfoDialog, noUserDisplay, ...props }: Args) {
|
||||||
const isAtRight = Client.myUserProfile?.id == userId
|
const isAtRight = Client.myUserProfile?.id == userId
|
||||||
|
|
||||||
const [nickName, setNickName] = React.useState("")
|
const [nickName, setNickName] = React.useState("")
|
||||||
@@ -123,7 +124,7 @@ export default function Message({ userId, rawData, renderHTML, message, openUser
|
|||||||
{...props}>
|
{...props}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: noUserDisplay ? 'none' : "flex",
|
||||||
justifyContent: isAtRight ? "flex-end" : "flex-start",
|
justifyContent: isAtRight ? "flex-end" : "flex-start",
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
@@ -168,7 +169,7 @@ export default function Message({ userId, rawData, renderHTML, message, openUser
|
|||||||
maxWidth: 'var(--whitesilk-widget-message-maxwidth)', // (window.matchMedia('(pointer: fine)') && "50%") || (window.matchMedia('(pointer: coarse)') && "77%"),
|
maxWidth: 'var(--whitesilk-widget-message-maxwidth)', // (window.matchMedia('(pointer: fine)') && "50%") || (window.matchMedia('(pointer: coarse)') && "77%"),
|
||||||
minWidth: "0%",
|
minWidth: "0%",
|
||||||
[isAtRight ? "marginRight" : "marginLeft"]: "55px",
|
[isAtRight ? "marginRight" : "marginLeft"]: "55px",
|
||||||
marginTop: "-5px",
|
marginTop: noUserDisplay ? '5px' : "-5px",
|
||||||
alignSelf: isAtRight ? "flex-end" : "flex-start",
|
alignSelf: isAtRight ? "flex-end" : "flex-start",
|
||||||
// boxShadow: isUsingFullDisplay ? 'inherit' : 'var(--mdui-elevation-level1)',
|
// boxShadow: isUsingFullDisplay ? 'inherit' : 'var(--mdui-elevation-level1)',
|
||||||
// padding: isUsingFullDisplay ? undefined : "13px",
|
// padding: isUsingFullDisplay ? undefined : "13px",
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export default function AllChatsList({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
}} {...props}>
|
}} {...props}>
|
||||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||||
paddingTop: '5px',
|
paddingTop: '12px',
|
||||||
paddingBottom: '13px',
|
paddingBottom: '13px',
|
||||||
position: 'sticky',
|
position: 'sticky',
|
||||||
top: '0',
|
top: '0',
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export default function ContactsList({
|
|||||||
zIndex: '10',
|
zIndex: '10',
|
||||||
}}>
|
}}>
|
||||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||||
marginTop: '5px',
|
paddingTop: '12px',
|
||||||
}}></mdui-text-field>
|
}}></mdui-text-field>
|
||||||
<mdui-list-item rounded style={{
|
<mdui-list-item rounded style={{
|
||||||
marginTop: '13px',
|
marginTop: '13px',
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default function RecentsList({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
}} {...props}>
|
}} {...props}>
|
||||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||||
marginTop: '5px',
|
paddingTop: '12px',
|
||||||
marginBottom: '13px',
|
marginBottom: '13px',
|
||||||
position: 'sticky',
|
position: 'sticky',
|
||||||
top: '0',
|
top: '0',
|
||||||
|
|||||||
Reference in New Issue
Block a user