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 useEventListener from "../useEventListener.ts"
|
||||
import Element_Message from "./Message.tsx"
|
||||
@@ -31,6 +31,7 @@ import JoinRequestsList from "./JoinRequestsList.tsx"
|
||||
import getUrlForFileByHash from "../../getUrlForFileByHash.ts"
|
||||
import escapeHTML from "../../escapeHtml.ts"
|
||||
import GroupMembersList from "./GroupMembersList.tsx"
|
||||
import isMobileUI from "../isMobileUI.ts"
|
||||
|
||||
interface Args extends React.HTMLAttributes<HTMLElement> {
|
||||
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) {
|
||||
const [messagesList, setMessagesList] = React.useState([] as Message[])
|
||||
const [chatInfo, setChatInfo] = React.useState({
|
||||
@@ -114,6 +127,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
||||
React.useEffect(() => {
|
||||
$(containerTabRef.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])
|
||||
|
||||
async function getChatInfoAndInit() {
|
||||
@@ -347,17 +361,18 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
overflowX: 'auto',
|
||||
}}>
|
||||
{
|
||||
chatInfo.is_member ? <>
|
||||
<mdui-tab value="Chat">{chatInfo.title}</mdui-tab>
|
||||
{chatInfo.type == 'group' && chatInfo.is_admin && <mdui-tab value="NewMemberRequests">加入请求</mdui-tab>}
|
||||
{chatInfo.type == 'group' && <mdui-tab value="GroupMembers">群组成员</mdui-tab>}
|
||||
<MduiTabFitSize value="Chat">{chatInfo.title}</MduiTabFitSize>
|
||||
{chatInfo.type == 'group' && chatInfo.is_admin && <MduiTabFitSize value="NewMemberRequests">加入请求</MduiTabFitSize>}
|
||||
{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>}
|
||||
<mdui-tab value="None" style={{ display: 'none' }}></mdui-tab>
|
||||
{chatInfo.type == 'group' && <MduiTabFitSize value="Settings">设置</MduiTabFitSize>}
|
||||
<MduiTabFitSize value="None" style={{ display: 'none' }}></MduiTabFitSize>
|
||||
</mdui-tabs>
|
||||
<div style={{
|
||||
flexGrow: '1',
|
||||
@@ -441,9 +456,20 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
||||
{
|
||||
(() => {
|
||||
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) => {
|
||||
const lastDate = date
|
||||
const lastUser = user
|
||||
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={{
|
||||
__html: DOMPurify.sanitize(markedInstance.parse(msg.text) as string, {
|
||||
@@ -455,6 +481,7 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
||||
],
|
||||
})
|
||||
}} /></SystemMessage> : <Element_Message
|
||||
noUserDisplay={lastUser == user && !shouldShowTime}
|
||||
rawData={msg.text}
|
||||
renderHTML={DOMPurify.sanitize(markedInstance.parse(msg.text) as string, sanitizeConfig)}
|
||||
message={msg}
|
||||
@@ -467,18 +494,18 @@ export default function ChatFragment({ target, showReturnButton, onReturnButtonC
|
||||
return (
|
||||
<>
|
||||
{
|
||||
msg.user_id != null &&
|
||||
(date.getMinutes() != lastDate.getMinutes() || date.getDate() != lastDate.getDate() || date.getMonth() != lastDate.getMonth() || date.getFullYear() != lastDate.getFullYear())
|
||||
shouldShowTime
|
||||
&& <mdui-tooltip content={`${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`}>
|
||||
<div style={{
|
||||
fontSize: '87%',
|
||||
marginTop: '10px',
|
||||
marginTop: '13px',
|
||||
marginBottom: '10px',
|
||||
}}>
|
||||
{
|
||||
(date.getFullYear() != lastDate.getFullYear() ? `${date.getFullYear()}年` : '')
|
||||
+ `${date.getMonth() + 1}月`
|
||||
+ `${date.getDate()}日`
|
||||
+ ` ${date.getHours()}:${date.getMinutes()}`
|
||||
+ ` ${timeAddZeroPrefix(date.getHours())}:${timeAddZeroPrefix(date.getMinutes())}`
|
||||
}
|
||||
</div>
|
||||
</mdui-tooltip>
|
||||
|
||||
@@ -13,14 +13,6 @@ import User from "../../api/client_data/User.ts"
|
||||
import getUrlForFileByHash from "../../getUrlForFileByHash.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) {
|
||||
const elements = new DOMParser().parseFromString(html, 'text/html').body.children
|
||||
// 纯文本直接处理
|
||||
@@ -72,7 +64,16 @@ function prettyFlatParsedMessage(html: string) {
|
||||
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 [nickName, setNickName] = React.useState("")
|
||||
@@ -123,7 +124,7 @@ export default function Message({ userId, rawData, renderHTML, message, openUser
|
||||
{...props}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
display: noUserDisplay ? 'none' : "flex",
|
||||
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%"),
|
||||
minWidth: "0%",
|
||||
[isAtRight ? "marginRight" : "marginLeft"]: "55px",
|
||||
marginTop: "-5px",
|
||||
marginTop: noUserDisplay ? '5px' : "-5px",
|
||||
alignSelf: isAtRight ? "flex-end" : "flex-start",
|
||||
// boxShadow: isUsingFullDisplay ? 'inherit' : 'var(--mdui-elevation-level1)',
|
||||
// padding: isUsingFullDisplay ? undefined : "13px",
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function AllChatsList({
|
||||
width: '100%',
|
||||
}} {...props}>
|
||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||
paddingTop: '5px',
|
||||
paddingTop: '12px',
|
||||
paddingBottom: '13px',
|
||||
position: 'sticky',
|
||||
top: '0',
|
||||
|
||||
@@ -74,7 +74,7 @@ export default function ContactsList({
|
||||
zIndex: '10',
|
||||
}}>
|
||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||
marginTop: '5px',
|
||||
paddingTop: '12px',
|
||||
}}></mdui-text-field>
|
||||
<mdui-list-item rounded style={{
|
||||
marginTop: '13px',
|
||||
|
||||
@@ -61,7 +61,7 @@ export default function RecentsList({
|
||||
width: '100%',
|
||||
}} {...props}>
|
||||
<mdui-text-field icon="search" type="search" clearable ref={searchRef} variant="outlined" placeholder="搜索..." style={{
|
||||
marginTop: '5px',
|
||||
paddingTop: '12px',
|
||||
marginBottom: '13px',
|
||||
position: 'sticky',
|
||||
top: '0',
|
||||
|
||||
Reference in New Issue
Block a user