rendering message

This commit is contained in:
balzack 2024-12-05 07:09:34 -08:00
parent e36528c308
commit 9e79e0b7e6
13 changed files with 8028 additions and 5223 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,5 @@
export const en = {
unknownContact: 'Unknown Contact',
unknown: 'Unknown',
sealed: 'Sealed',
notes: 'Notes',
@ -252,6 +253,7 @@ export const en = {
}
export const fr = {
unknownContact: 'Contact inconnu',
unknown: 'Inconnu',
sealed: 'Scellé',
notes: 'Notes',
@ -506,6 +508,7 @@ export const fr = {
}
export const sp = {
unkownContact: 'Contacto Desconocido',
unknown: 'Desconocido',
sealed: 'Sellado',
notes: 'Notas',
@ -759,6 +762,7 @@ export const sp = {
}
export const pt = {
unknownContact: 'Contato Desconhecido',
unknown: 'Desconhecido',
sealed: 'Selado',
notes: 'Notas',
@ -1012,6 +1016,7 @@ export const pt = {
}
export const de = {
unknwonContact: 'Unbekannter Kontakt',
unknown: 'Unbekannt',
sealed: 'Versiegelt',
notes: 'Notizen',
@ -1265,6 +1270,7 @@ export const de = {
}
export const ru = {
unknownContact: 'Неизвестный контакт',
unknown: 'Неизвестно',
sealed: 'Запечатано',
notes: 'Заметки',

View File

@ -34,8 +34,6 @@
flex-direction: column;
height: fit-content;
width: 100%;
padding-left: 32px;
padding-right: 32px;
}
.add {

View File

@ -15,6 +15,7 @@ export function Conversation() {
};
const topics = state.topics.map((topic, idx) => {
const { host } = state;
const card = state.cards.get(topic.guid) || null;
const profile = state.profile?.guid === topic.guid ? state.profile : null;
return (
@ -23,6 +24,11 @@ export function Conversation() {
topic={topic}
card={card}
profile={profile}
host={host}
getAssetUrl={actions.getAssetUrl}
strings={state.strings}
timeFormat={state.timeFormat}
dateFormat={state.dateFormat}
/>
)
})

View File

@ -12,9 +12,13 @@ export function useConversation() {
const [state, setState] = useState({
focus: null as Focus | null,
layout: null,
strings: display.state.strings,
timeFormat: display.state.timeFormat,
dateFormat: display.state.dateFormat,
topics: [] as Topic[],
profile: null as Profile | null,
cards: new Map<string, Card>(),
host: false,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -23,8 +27,8 @@ export function useConversation() {
}
useEffect(() => {
const { layout } = display.state
updateState({ layout })
const { layout, timeFormat, dateFormat } = display.state
updateState({ layout, timeFormat, dateFormat })
}, [display.state])
useEffect(() => {
@ -54,6 +58,11 @@ export function useConversation() {
updateState({ profile });
}
const setDetail = (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => {
if (focused.cardId) {
updateState({ host: false });
} else {
updateState({ host: true });
}
console.log(focused);
}
focus.addTopicListener(setTopics);
@ -79,8 +88,14 @@ export function useConversation() {
focus.viewMoreTopics();
}
},
getAssetUrl: async (topicId: string, assetId: string) => {
const { focus } = app.state;
if (!focus) {
throw new Error('no channel in focus');
}
return await focus.getTopicAssetUrl(topicId, assetId, (percent: number)=>true);
},
add: async (file: File) => {
const { focus } = app.state;
if (focus) {
const asset = {

View File

@ -0,0 +1,75 @@
.topic {
display: flex;
flex-direction: column;
width: 100%;
.assets {
width: 100%;
height: 32px;
}
.content {
display: flex;
flex-direction: row;
align-items: flex-start;
width: calc(100% - 32px);
margin-left: 16px;
margin-right: 16px;
padding-left: 8px;
padding-right: 8px;
padding-top: 12px;
border-top: 1px solid var(--mantine-color-text-8);
.logo {
width: 40px;
height: 40px;
}
.body {
display: flex;
flex-grow: 1;
flex-direction: column;
padding-left: 8px;
padding-right: 8px;
.header {
display: flex;
flex-direction: row;
align-items: flex-start;
width: 100%;
line-height: 16px;
padding-bottom: 4px;
gap: 16px;
&:hover {
.options {
display: flex;
flex-grow: 1;
justify-content: flex-end;
}
}
.options {
display: none;
}
.name {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
.timestamp {
font-size: 0.8rem;
}
.unknown {
font-style: italic;
color: var(--mantine-color-text-7);
}
}
}
}
}
}

View File

@ -1,6 +1,81 @@
import { useEffect, useState } from 'react';
import { avatar } from '../constants/Icons'
import { Topic, Card, Profile } from 'databag-client-sdk';
import classes from './Message.module.css'
import { Image } from '@mantine/core'
export function Message({ topic, card, profile }: { topic: Topic, card: Card | null, profile: Profile | null }) {
console.log(card, profile);
return <div>CREATED: { topic.created }</div>
function getTimestamp(created: number, timeFormat: string, dateFormat: string) {
const now = Math.floor((new Date()).getTime() / 1000)
const date = new Date(created * 1000);
const offset = now - created;
if(offset < 86400) {
if (timeFormat === '12h') {
return date.toLocaleTimeString("en-US", {hour: 'numeric', minute:'2-digit'});
}
else {
return date.toLocaleTimeString("en-GB", {hour: 'numeric', minute:'2-digit'});
}
}
else if (offset < 31449600) {
if (dateFormat === 'mm/dd') {
return date.toLocaleDateString("en-US", {day: 'numeric', month:'numeric'});
}
else {
return date.toLocaleDateString("en-GB", {day: 'numeric', month:'numeric'});
}
}
else {
if (dateFormat === 'mm/dd') {
return date.toLocaleDateString("en-US");
}
else {
return date.toLocaleDateString("en-GB");
}
}
}
export function Message({ topic, card, profile, host, getAssetUrl, strings, timeFormat, dateFormat }: { topic: Topic, card: Card | null, profile: Profile | null, host: boolean, getAssetUrl: (topicId: string, assetId: string)=>Promise<string>, strings: any, timeFormat: string, dateFormat: string }) {
useEffect(() => {
console.log("NEW MESSAGE");
}, []);
const { locked, data, created } = topic;
const { name, handle, node } = profile || card || { name: null, handle: null, node: null }
const { text, textColor, textSize } = data || { text: null, textColor: null, textSize: null }
const textStyle = textColor && textSize ? { color: textColor, fontSize: textSize } : textColor ? { color: textColor } : textSize ? { fontSize: textSize } : {}
const logoUrl = profile ? profile.imageUrl : card ? card.imageUrl : avatar;
const timestamp = getTimestamp(created, timeFormat, dateFormat);
const options = [];
const assets = [];
return (
<div className={classes.topic}>
<div className={classes.content}>
<Image radius="sm" className={classes.logo} src={logoUrl} />
<div className={classes.body}>
<div className={classes.header}>
<div className={classes.name}>
{ name && (
<span>{ name }</span>
)}
{ !name && handle && (
<span>{ `${handle}${node ? '/' + node : ''}` }</span>
)}
{ !name && !handle && (
<span className={classes.unknown}>{ strings.unknownContact }</span>
)}
<span className={classes.timestamp}> { timestamp }</span>
</div>
<div className={classes.options}>OPTIONS</div>
</div>
{ text && (
<div style={textStyle}>{ text }</div>
)}
</div>
</div>
<div className={classes.assets}>ASSETS</div>
</div>
)
}

View File

@ -23,6 +23,7 @@
height: 100%;
.left {
flex-shrink: 0;
display: flex;
flex-direction: column;
height: 100%;

File diff suppressed because it is too large Load Diff

View File

@ -987,6 +987,7 @@ export class ContactModule implements Contact {
blocked: this.isChannelBlocked(cardId, channelId),
unread: this.isChannelUnread(cardId, channelId),
sealed: detail.sealed,
locked: detail.sealed && (!this.seal || !channelKey),
dataType: detail.dataType,
data: this.parse(channelData),
created: detail.created,

View File

@ -738,7 +738,7 @@ export class FocusModule implements Focus {
await this.removeRemoteChannelTopic(topicId);
}
public async getTopicAssetUrl(topicId: string, assetId: string, progress: (percent: number) => boolean): Promise<string> {
public async getTopicAssetUrl(topicId: string, assetId: string, progress: null | (percent: number) => boolean): Promise<string> {
const entry = this.topicEntries.get(topicId);
if (!entry) {
throw new Error('topic entry not found');
@ -974,6 +974,7 @@ export class FocusModule implements Focus {
guid: item.detail.guid,
blocked: this.isTopicBlocked(topicId),
sealed: item.detail.sealed,
locked: item.detail.sealed && (!this.sealEnabled || !this.channelKey),
dataType: item.detail.dataType,
created: item.detail.created,
updated: item.detail.updated,

View File

@ -502,7 +502,7 @@ export class StreamModule {
}
private setChannel(channelId: string, item: ChannelItem): Channel {
const { summary, detail } = item;
const { summary, detail, channelKey } = item;
const channelData = detail.sealed ? item.unsealedDetail : detail.data || '{}';
const topicData = summary.sealed ? item.unsealedSummary : summary.data || '{}';
@ -522,6 +522,7 @@ export class StreamModule {
blocked: this.isChannelBlocked(channelId),
unread: this.isChannelUnread(channelId),
sealed: detail.sealed,
locked: detail.sealed && (!this.seal || !channelKey),
dataType: detail.dataType,
data: this.parse(channelData),
created: detail.created,

View File

@ -53,6 +53,7 @@ export type Channel = {
blocked: boolean;
unread: boolean;
sealed: boolean;
locked: boolean;
dataType: string;
data: any;
created: number;
@ -99,6 +100,7 @@ export type Topic = {
topicId: string;
guid: string;
sealed: boolean;
locked: boolean;
blocked: boolean;
dataType: string;
data: any;