fixing lint errors

This commit is contained in:
balzack 2025-03-24 16:43:06 -07:00
parent 6c4f0f1181
commit ae9a72b8d6
35 changed files with 71 additions and 83 deletions

View File

@ -5,9 +5,9 @@ export class StagingFiles implements Staging {
public async clear(): Promise<void> {} public async clear(): Promise<void> {}
private base64ToUint8Array(base64: string): Uint8Array { private base64ToUint8Array(base64: string): Uint8Array {
var binaryString = atob(base64); const binaryString = atob(base64);
var bytes = new Uint8Array(binaryString.length); const bytes = new Uint8Array(binaryString.length);
for (var i = 0; i < binaryString.length; i++) { for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i); bytes[i] = binaryString.charCodeAt(i);
} }
return bytes; return bytes;
@ -22,15 +22,15 @@ export class StagingFiles implements Staging {
return window.btoa(binary); return window.btoa(binary);
} }
private loadFileData(file: any): Promise<ArrayBuffer> { private loadFileData(file: File): Promise<ArrayBuffer> {
return new Promise(resolve => { return new Promise(resolve => {
const reader = new FileReader() const reader = new FileReader()
reader.onloadend = (res) => { resolve(reader.result as ArrayBuffer) } reader.onloadend = () => { resolve(reader.result as ArrayBuffer) }
reader.readAsArrayBuffer(file) reader.readAsArrayBuffer(file)
}) })
}; };
public async read(source: any): Promise<{ size: number, getData: (position: number, length: number)=>Promise<string>, close: ()=>Promise<void> }> { public async read(source: File): Promise<{ size: number, getData: (position: number, length: number)=>Promise<string>, close: ()=>Promise<void> }> {
const data = await this.loadFileData(source); const data = await this.loadFileData(source);
const size = data.byteLength; const size = data.byteLength;
const getData = async (position: number, length: number) => { const getData = async (position: number, length: number) => {

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import classes from './Accounts.module.css' import classes from './Accounts.module.css'
import { useAccounts } from './useAccounts.hook' import { useAccounts } from './useAccounts.hook'
import { Modal, Divider, Text, ActionIcon, Button } from '@mantine/core' import { Modal, Text, ActionIcon, Button } from '@mantine/core'
import { IconUserPlus, IconUserCheck, IconCopy, IconCheck, IconReload, IconSettings, IconLockOpen2, IconUserCancel, IconTrash } from '@tabler/icons-react' import { IconUserPlus, IconUserCheck, IconCopy, IconCheck, IconReload, IconSettings, IconLockOpen2, IconUserCancel, IconTrash } from '@tabler/icons-react'
import { Card } from '../card/Card' import { Card } from '../card/Card'
import { Colors } from '../constants/Colors'; import { Colors } from '../constants/Colors';
@ -176,7 +176,7 @@ export function Accounts({ openSetup }: { openSetup: ()=>void }) {
<div className={classes.content}> <div className={classes.content}>
<div className={classes.header}> <div className={classes.header}>
{ state.layout !== 'large' && ( { state.layout !== 'large' && (
<ActionIcon className={classes.action} variant="light" onClick={actions.reload} loading={loading}> <ActionIcon className={classes.action} variant="light" onClick={loadAccounts} loading={loading}>
<IconReload /> <IconReload />
</ActionIcon> </ActionIcon>
)} )}
@ -184,7 +184,7 @@ export function Accounts({ openSetup }: { openSetup: ()=>void }) {
<Text className={classes.title}>{ state.strings.accounts }</Text> <Text className={classes.title}>{ state.strings.accounts }</Text>
</div> </div>
{ state.layout === 'large' && ( { state.layout === 'large' && (
<ActionIcon className={classes.action} variant="light" onClick={actions.reload} loading={loading}> <ActionIcon className={classes.action} variant="light" onClick={loadAccounts} loading={loading}>
<IconReload /> <IconReload />
</ActionIcon> </ActionIcon>
)} )}

View File

@ -1,4 +1,4 @@
import {useEffect, useState, useContext, useRef} from 'react'; import {useEffect, useState, useContext} from 'react';
import {AppContext} from '../context/AppContext'; import {AppContext} from '../context/AppContext';
import {DisplayContext} from '../context/DisplayContext'; import {DisplayContext} from '../context/DisplayContext';
import {ContextType} from '../context/ContextType'; import {ContextType} from '../context/ContextType';
@ -15,6 +15,7 @@ export function useAccounts() {
secretText: '', secretText: '',
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateState = (value: any) => { const updateState = (value: any) => {
setState(s => ({...s, ...value})); setState(s => ({...s, ...value}));
}; };

View File

@ -34,7 +34,7 @@ export function useBase() {
updateState({ cardSet: cards.length > 0 }); updateState({ cardSet: cards.length > 0 });
} }
const setChannels = ({ channels, cardId }: { channels: Channel[]; cardId: string | null }) => { const setChannels = ({ channels, cardId }: { channels: Channel[]; cardId: string | null }) => {
updateState({ channelSet: channels.length > 0 }); updateState({ channelSet: cardId && channels.length > 0 });
} }
const setContent = (loaded: boolean) => { const setContent = (loaded: boolean) => {
updateState({ contentSet: loaded }); updateState({ contentSet: loaded });

View File

@ -1,7 +1,6 @@
import React, { useRef, useEffect, useState } from 'react'; import React, { useRef, useEffect, useState } from 'react';
import { useCall } from './useCall.hook'; import { useCall } from './useCall.hook';
import classes from './Call.module.css' import classes from './Call.module.css'
import { Card as Contact } from '../card/Card';
import { Colors } from '../constants/Colors'; import { Colors } from '../constants/Colors';
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
import { Image, Text, ActionIcon } from '@mantine/core' import { Image, Text, ActionIcon } from '@mantine/core'
@ -12,9 +11,6 @@ export function Call() {
const [ending, setEnding] = useState(false); const [ending, setEnding] = useState(false);
const [applyingAudio, setApplyingAudio] = useState(false); const [applyingAudio, setApplyingAudio] = useState(false);
const [applyingVideo, setApplyingVideo] = useState(false); const [applyingVideo, setApplyingVideo] = useState(false);
const [accepting, setAccepting] = useState(null as null|string);
const [ignoring, setIgnoring] = useState(null as null|string);
const [declining, setDeclining] = useState(null as null|string);
const remote = useRef(null as null|HTMLVideoElement); const remote = useRef(null as null|HTMLVideoElement);
const local = useRef(null as null|HTMLVideoElement); const local = useRef(null as null|HTMLVideoElement);

View File

@ -4,7 +4,7 @@ import { type Card } from 'databag-client-sdk'
import { useCalling } from './useCalling.hook'; import { useCalling } from './useCalling.hook';
import { Card as Contact } from '../card/Card'; import { Card as Contact } from '../card/Card';
import { Loader, Image, Text, ActionIcon } from '@mantine/core' import { Loader, Image, Text, ActionIcon } from '@mantine/core'
import { IconEyeX, IconPhone, IconPhoneOff, IconMicrophone, IconMicrophoneOff, IconVideo, IconVideoOff } from '@tabler/icons-react' import { IconEyeX, IconPhone, IconMicrophone, IconMicrophoneOff, IconVideo, IconVideoOff } from '@tabler/icons-react'
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
import { Colors } from '../constants/Colors' import { Colors } from '../constants/Colors'

View File

@ -1,4 +1,4 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useEffect } from 'react'
import { RingContext } from '../context/RingContext' import { RingContext } from '../context/RingContext'
import { DisplayContext } from '../context/DisplayContext' import { DisplayContext } from '../context/DisplayContext'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'

View File

@ -3,8 +3,7 @@ import { useContacts } from './useContacts.hook'
import { Text, ActionIcon, TextInput, Button } from '@mantine/core' import { Text, ActionIcon, TextInput, Button } from '@mantine/core'
import { IconUserCheck, IconCancel, IconRefresh, IconSearch, IconUserPlus, IconSortAscending, IconSortDescending, IconMessage2, IconPhone } from '@tabler/icons-react' import { IconUserCheck, IconCancel, IconRefresh, IconSearch, IconUserPlus, IconSortAscending, IconSortDescending, IconMessage2, IconPhone } from '@tabler/icons-react'
import classes from './Contacts.module.css' import classes from './Contacts.module.css'
import { type Card } from 'databag-client-sdk'; import { Card } from '../card/Card'
import { Card as Contact } from '../card/Card'
import { ProfileParams } from '../profile/Profile' import { ProfileParams } from '../profile/Profile'
import { Colors } from '../constants/Colors' import { Colors } from '../constants/Colors'
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
@ -48,8 +47,12 @@ export function Contacts({ openRegistry, openContact, textContact, closeContacts
const phone = <IconPhone size={24} /> const phone = <IconPhone size={24} />
const text = <IconMessage2 size={24} /> const text = <IconMessage2 size={24} />
return [ return [
<Action key="phone" icon={phone} color={Colors.connected} select={async () => { await actions.call(card), closeContacts() }} strings={state.strings} />, <Action key="phone" icon={phone} color={Colors.connected}
<Action key="text" icon={text} color={Colors.connected} select={async () => textContact(card.cardId)} strings={state.strings} />, select={async () => { await actions.call(card); closeContacts() }}
strings={state.strings} />,
<Action key="text" icon={text} color={Colors.connected}
select={async () => textContact(card.cardId)}
strings={state.strings} />,
] ]
} else if (status === 'offsync') { } else if (status === 'offsync') {
const resync = <IconRefresh size={24} /> const resync = <IconRefresh size={24} />
@ -76,7 +79,7 @@ export function Contacts({ openRegistry, openContact, textContact, closeContacts
} }
return ( return (
<Contact key={idx} className={classes.card} imageUrl={card.imageUrl} name={card.name} handle={card.handle} node={card.node} placeholder={state.strings.name} select={select} actions={options} /> <Card key={idx} className={classes.card} imageUrl={card.imageUrl} name={card.name} handle={card.handle} node={card.node} placeholder={state.strings.name} select={select} actions={options} />
) )
}) })

View File

@ -1,5 +1,4 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useEffect, useRef } from 'react'
import { DisplayContext } from '../context/DisplayContext';
import { AppContext } from '../context/AppContext' import { AppContext } from '../context/AppContext'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'
import { Link, type Card } from 'databag-client-sdk'; import { Link, type Card } from 'databag-client-sdk';
@ -8,13 +7,13 @@ const CLOSE_POLL_MS = 100;
export function useRingContext() { export function useRingContext() {
const app = useContext(AppContext) as ContextType; const app = useContext(AppContext) as ContextType;
const display = useContext(DisplayContext) as ContextType;
const call = useRef(null as { peer: RTCPeerConnection, link: Link, candidates: RTCIceCandidate[] } | null); const call = useRef(null as { peer: RTCPeerConnection, link: Link, candidates: RTCIceCandidate[] } | null);
const localStream = useRef(null as null|MediaStream); const localStream = useRef(null as null|MediaStream);
const localAudio = useRef(null as null|MediaStreamTrack); const localAudio = useRef(null as null|MediaStreamTrack);
const localVideo = useRef(null as null|MediaStreamTrack); const localVideo = useRef(null as null|MediaStreamTrack);
const remoteStream = useRef(null as null|MediaStream); const remoteStream = useRef(null as null|MediaStream);
const updatingPeer = useRef(false); const updatingPeer = useRef(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const peerUpdate = useRef([] as {type: string, data?: any}[]); const peerUpdate = useRef([] as {type: string, data?: any}[]);
const connecting = useRef(false); const connecting = useRef(false);
const closing = useRef(false); const closing = useRef(false);
@ -75,7 +74,6 @@ export function useRingContext() {
const linkStatus = async (status: string) => { const linkStatus = async (status: string) => {
if (call.current) { if (call.current) {
const { peer, link } = call.current;
if (status === 'connected') { if (status === 'connected') {
const connectedTime = Math.floor((new Date()).getTime() / 1000); const connectedTime = Math.floor((new Date()).getTime() / 1000);
updateState({ connected: true, connectedTime }); updateState({ connected: true, connectedTime });
@ -91,6 +89,7 @@ export function useRingContext() {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updatePeer = async (type: string, data?: any) => { const updatePeer = async (type: string, data?: any) => {
peerUpdate.current.push({ type, data }); peerUpdate.current.push({ type, data });
@ -101,11 +100,12 @@ export function useRingContext() {
const { type, data } = peerUpdate.current.shift() || { type: '' }; const { type, data } = peerUpdate.current.shift() || { type: '' };
try { try {
switch (type) { switch (type) {
case 'negotiate': case 'negotiate': {
const description = await peer.createOffer(); const description = await peer.createOffer();
await peer.setLocalDescription(description); await peer.setLocalDescription(description);
await link.sendMessage({ description }); await link.sendMessage({ description });
break; break;
}
case 'candidate': case 'candidate':
await link.sendMessage({ data }); await link.sendMessage({ data });
break; break;
@ -183,6 +183,7 @@ export function useRingContext() {
const candidates = [] as RTCIceCandidate[]; const candidates = [] as RTCIceCandidate[];
call.current = { peer, link, candidates }; call.current = { peer, link, candidates };
link.setStatusListener(linkStatus); link.setStatusListener(linkStatus);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
link.setMessageListener((msg: any) => updatePeer('message', msg)); link.setMessageListener((msg: any) => updatePeer('message', msg));
updateState({ calling: card, failed: false, connected: false, connectedTime: 0, updateState({ calling: card, failed: false, connected: false, connectedTime: 0,
audioEnabled: false, videoEnabled: false, localVideo: false, remoteVideo: false, audioEnabled: false, videoEnabled: false, localVideo: false, remoteVideo: false,
@ -209,7 +210,7 @@ export function useRingContext() {
localAudio.current = null; localAudio.current = null;
} }
localStream.current = null; localStream.current = null;
remoteStream.current = null, remoteStream.current = null;
peerUpdate.current = []; peerUpdate.current = [];
updateState({ calling: null, connected: false, connectedTime: 0, fullscreen: false, updateState({ calling: null, connected: false, connectedTime: 0, fullscreen: false,
failed: false, localStream: null, remoteStream: null, localVideo: false, remoteVideo: false }); failed: false, localStream: null, remoteStream: null, localVideo: false, remoteVideo: false });
@ -219,19 +220,18 @@ export function useRingContext() {
const transmit = (ice: { urls: string; username: string; credential: string }[]) => { const transmit = (ice: { urls: string; username: string; credential: string }[]) => {
const peerConnection = new RTCPeerConnection({ iceServers: ice }); const peerConnection = new RTCPeerConnection({ iceServers: ice });
peerConnection.addEventListener( 'connectionstatechange', event => { peerConnection.addEventListener( 'connectionstatechange', event => {
console.log("????CONNECTION STATE", event); console.log(peerConnection, event);
console.log(peerConnection);
}); });
peerConnection.addEventListener( 'icecandidate', event => { peerConnection.addEventListener( 'icecandidate', event => {
updatePeer('candidate', event.candidate); updatePeer('candidate', event.candidate);
}); });
peerConnection.addEventListener( 'icecandidateerror', event => { peerConnection.addEventListener( 'icecandidateerror', event => {
console.log("ICE ERROR"); console.log("ICE ERROR", event);
}); });
peerConnection.addEventListener( 'iceconnectionstatechange', event => { peerConnection.addEventListener( 'iceconnectionstatechange', event => {
console.log("ICE STATE CHANGE", event); console.log("ICE STATE CHANGE", event);
}); });
peerConnection.addEventListener( 'negotiationneeded', event => { peerConnection.addEventListener( 'negotiationneeded', () => {
updatePeer('negotiate'); updatePeer('negotiate');
}); });
peerConnection.addEventListener( 'signalingstatechange', event => { peerConnection.addEventListener( 'signalingstatechange', event => {

View File

@ -1,8 +1,7 @@
import React, {useState, useEffect, useRef, useCallback} from 'react' import React, {useState, useEffect, useRef} from 'react'
import { Focus } from 'databag-client-sdk'
import classes from './Conversation.module.css' import classes from './Conversation.module.css'
import { useConversation } from './useConversation.hook'; import { useConversation } from './useConversation.hook';
import { IconSend, IconTextSize, IconTextColor, IconVideo, IconFile, IconDisc, IconCamera, IconX, IconSettings, IconHome, IconServer, IconShield, IconLock, IconExclamationCircle } from '@tabler/icons-react' import { IconSend, IconTextSize, IconTextColor, IconVideo, IconFile, IconDisc, IconCamera, IconSettings, IconHome, IconServer, IconShield, IconExclamationCircle } from '@tabler/icons-react'
import { CloseButton, Menu, Divider, Text, Textarea, ActionIcon, Loader } from '@mantine/core' import { CloseButton, Menu, Divider, Text, Textarea, ActionIcon, Loader } from '@mantine/core'
import { Message } from '../message/Message'; import { Message } from '../message/Message';
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
@ -15,7 +14,6 @@ import AnimateHeight from 'react-animate-height';
import { useResizeDetector } from 'react-resize-detector'; import { useResizeDetector } from 'react-resize-detector';
const PAD_HEIGHT = (1024 - 64); const PAD_HEIGHT = (1024 - 64);
const LOAD_DEBOUNCE = 1000;
export type MediaAsset = { export type MediaAsset = {
encrypted?: { type: string, thumb: string, label: string, extension: string, parts: { blockIv: string, partId: string }[] }, encrypted?: { type: string, thumb: string, label: string, extension: string, parts: { blockIv: string, partId: string }[] },
@ -28,14 +26,13 @@ export type MediaAsset = {
export function Conversation({ openDetails }: { openDetails: ()=>void }) { export function Conversation({ openDetails }: { openDetails: ()=>void }) {
const thread = useRef(null as HTMLDivElement | null); const thread = useRef(null as HTMLDivElement | null);
const scrollPos = useRef(0); const scrollPos = useRef(0);
const debounce = useRef(false);
const [sending, setSending] = useState(false); const [sending, setSending] = useState(false);
const { state, actions } = useConversation(); const { state, actions } = useConversation();
const attachImage = useRef({ click: ()=>{} } as HTMLInputElement); const attachImage = useRef({ click: ()=>{} } as HTMLInputElement);
const attachVideo = useRef({ click: ()=>{} } as HTMLInputElement); const attachVideo = useRef({ click: ()=>{} } as HTMLInputElement);
const attachAudio = useRef({ click: ()=>{} } as HTMLInputElement); const attachAudio = useRef({ click: ()=>{} } as HTMLInputElement);
const attachBinary = useRef({ click: ()=>{} } as HTMLInputElement); const attachBinary = useRef({ click: ()=>{} } as HTMLInputElement);
const { width, height, ref } = useResizeDetector(); const { height, ref } = useResizeDetector();
const input = useRef(null as null | HTMLTextAreaElement); const input = useRef(null as null | HTMLTextAreaElement);
const addImage = (image: File | undefined) => { const addImage = (image: File | undefined) => {

View File

@ -6,7 +6,7 @@ import audio from '../../images/audio.png'
import { IconX } from '@tabler/icons-react' import { IconX } from '@tabler/icons-react'
export function AudioFile({ source, updateLabel, disabled, remove }: {source: File, updateLabel: (label: string)=>void, disabled: boolean, remove: ()=>void}) { export function AudioFile({ source, updateLabel, disabled, remove }: {source: File, updateLabel: (label: string)=>void, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useAudioFile(source); const { state } = useAudioFile(source);
useEffect(() => { useEffect(() => {
updateLabel(state.label); updateLabel(state.label);

View File

@ -6,7 +6,7 @@ import binary from '../../images/binary.png'
import { IconX } from '@tabler/icons-react' import { IconX } from '@tabler/icons-react'
export function BinaryFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) { export function BinaryFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useBinaryFile(source); const { state } = useBinaryFile(source);
return ( return (
<div className={classes.asset}> <div className={classes.asset}>

View File

@ -5,7 +5,7 @@ import classes from './ImageFile.module.css'
import { IconX } from '@tabler/icons-react' import { IconX } from '@tabler/icons-react'
export function ImageFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) { export function ImageFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useImageFile(source); const { state } = useImageFile(source);
return ( return (
<div className={classes.asset}> <div className={classes.asset}>

View File

@ -1,10 +1,9 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useEffect } from 'react'
import { AppContext } from '../context/AppContext' import { AppContext } from '../context/AppContext'
import { DisplayContext } from '../context/DisplayContext' import { DisplayContext } from '../context/DisplayContext'
import { Focus, FocusDetail, Topic, Profile, Card, AssetType, AssetSource, HostingMode, TransformType } from 'databag-client-sdk' import { Focus, FocusDetail, Topic, Profile, Card, AssetType, AssetSource, TransformType } from 'databag-client-sdk'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'
import Resizer from "react-image-file-resizer"; import Resizer from "react-image-file-resizer";
import { placeholder } from '../constants/Icons';
const IMAGE_SCALE_SIZE = (128 * 1024); const IMAGE_SCALE_SIZE = (128 * 1024);
const GIF_TYPE = 'image/gif'; const GIF_TYPE = 'image/gif';
@ -19,7 +18,7 @@ function getImageThumb(file: File) {
reader.onload = function () { reader.onload = function () {
resolve(reader.result as string); resolve(reader.result as string);
}; };
reader.onerror = function (error) { reader.onerror = function () {
reject(); reject();
}; };
} }
@ -35,12 +34,12 @@ function getImageThumb(file: File) {
function getVideoThumb(file: File, position?: number) { function getVideoThumb(file: File, position?: number) {
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
const url = URL.createObjectURL(file); const url = URL.createObjectURL(file);
var video = document.createElement("video"); const video = document.createElement("video");
var timeupdate = function (ev: any) { const timeupdate = function () {
video.removeEventListener("timeupdate", timeupdate); video.removeEventListener("timeupdate", timeupdate);
video.pause(); video.pause();
setTimeout(() => { setTimeout(() => {
var canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
if (!canvas) { if (!canvas) {
reject(); reject();
} else { } else {
@ -57,7 +56,7 @@ function getVideoThumb(file: File, position?: number) {
reject(); reject();
} else { } else {
context.drawImage(video, 0, 0, canvas.width, canvas.height); context.drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL("image/jpeg", 0.75); const image = canvas.toDataURL("image/jpeg", 0.75);
resolve(image); resolve(image);
} }
} }
@ -116,6 +115,7 @@ export function useConversation() {
setState((s) => ({ ...s, ...value })) setState((s) => ({ ...s, ...value }))
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateAsset = (index: number, value: any) => { const updateAsset = (index: number, value: any) => {
setState((s) => { setState((s) => {
s.assets[index] = { ...s.assets[index], ...value }; s.assets[index] = { ...s.assets[index], ...value };

View File

@ -6,7 +6,7 @@ import { IconX, IconChevronLeft, IconChevronRight } from '@tabler/icons-react'
import { placeholder } from '../../constants/Icons' import { placeholder } from '../../constants/Icons'
export function VideoFile({ source, thumbPosition, disabled, remove }: {source: File, thumbPosition: (position: number)=>void, disabled: boolean, remove: ()=>void}) { export function VideoFile({ source, thumbPosition, disabled, remove }: {source: File, thumbPosition: (position: number)=>void, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useVideoFile(source); const { state } = useVideoFile(source);
const [ error, setError ] = useState(false); const [ error, setError ] = useState(false);
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const position = useRef(0); const position = useRef(0);

View File

@ -1,8 +1,8 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { useDetails } from './useDetails.hook' import { useDetails } from './useDetails.hook'
import classes from './Details.module.css' import classes from './Details.module.css'
import { IconUserCog, IconEyeOff, IconAlertHexagon, IconMessageX, IconLogout2, IconHome, IconServer, IconShield, IconShieldOff, IconCalendarClock, IconExclamationCircle, IconX, IconEdit, IconDeviceFloppy, IconArrowBack, IconLabel } from '@tabler/icons-react' import { IconUserCog, IconEyeOff, IconAlertHexagon, IconMessageX, IconLogout2, IconHome, IconServer, IconShield, IconShieldOff, IconCalendarClock, IconExclamationCircle, IconX, IconDeviceFloppy, IconArrowBack, IconLabel } from '@tabler/icons-react'
import { Switch, Button, Modal, Divider, Text, Textarea, Image, TextInput, ActionIcon } from '@mantine/core' import { Switch, Button, Modal, Divider, Text, TextInput, ActionIcon } from '@mantine/core'
import { Card } from '../card/Card'; import { Card } from '../card/Card';
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
import { useDisclosure } from '@mantine/hooks' import { useDisclosure } from '@mantine/hooks'

View File

@ -69,6 +69,8 @@ export function useDetails() {
}, [display.state]); }, [display.state]);
useEffect(() => { useEffect(() => {
console.log("DETAILS", state.detail);
const hostCard = state.cards.find(entry => entry.cardId == state.cardId); const hostCard = state.cards.find(entry => entry.cardId == state.cardId);
const profileRemoved = state.detail?.members ? state.detail.members.filter(member => state.profile?.guid != member.guid) : []; const profileRemoved = state.detail?.members ? state.detail.members.filter(member => state.profile?.guid != member.guid) : [];
const contactCards = profileRemoved.map(member => state.cards.find(card => card.guid === member.guid)); const contactCards = profileRemoved.map(member => state.cards.find(card => card.guid === member.guid));

View File

@ -1,4 +1,4 @@
import { useRef, useEffect, useState, useCallback } from 'react'; import React, { useRef, useEffect, useState, useCallback } from 'react';
import { avatar } from '../constants/Icons' import { avatar } from '../constants/Icons'
import { Topic, Card, Profile } from 'databag-client-sdk'; import { Topic, Card, Profile } from 'databag-client-sdk';
import classes from './Message.module.css' import classes from './Message.module.css'
@ -126,16 +126,16 @@ export function Message({ topic, card, profile, host }: { topic: Topic, card: Ca
const hostPattern = new RegExp('^https?:\\/\\/', 'i'); const hostPattern = new RegExp('^https?:\\/\\/', 'i');
let plain = ''; let plain = '';
let clickable = []; const clickable = [];
const parsed = !text ? [] : text.split(' '); const parsed = !text ? [] : text.split(' ');
if (parsed?.length > 0) { if (parsed?.length > 0) {
const words = parsed as string[]; const words = parsed as string[];
words.forEach((word, index) => { words.forEach((word, index) => {
if (!!urlPattern.test(word)) { if (urlPattern.test(word)) {
clickable.push(<span key={index}>{ plain }</span>); clickable.push(<span key={index}>{ plain }</span>);
plain = ''; plain = '';
const url = !!hostPattern.test(word) ? word : `https://${word}`; const url = hostPattern.test(word) ? word : `https://${word}`;
clickable.push(<a key={'link-'+index} target="_blank" rel="noopener noreferrer" href={sanitizeUrl(url)}>{ `${word} ` }</a>); clickable.push(<a key={'link-'+index} target="_blank" rel="noopener noreferrer" href={sanitizeUrl(url)}>{ `${word} ` }</a>);
} }
else { else {
@ -166,8 +166,6 @@ export function Message({ topic, card, profile, host }: { topic: Topic, card: Ca
} }
} }
const options = [];
const media = !assets ? [] : assets.map((asset: MediaAsset, index: number) => { const media = !assets ? [] : assets.map((asset: MediaAsset, index: number) => {
if (asset.image || asset.encrypted?.type === 'image') { if (asset.image || asset.encrypted?.type === 'image') {
return <ImageAsset key={index} topicId={topicId} asset={asset as MediaAsset} /> return <ImageAsset key={index} topicId={topicId} asset={asset as MediaAsset} />

View File

@ -1,6 +1,5 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useRef } from 'react'
import { AppContext } from '../../context/AppContext' import { AppContext } from '../../context/AppContext'
import { Focus } from 'databag-client-sdk'
import { ContextType } from '../../context/ContextType' import { ContextType } from '../../context/ContextType'
import { MediaAsset } from '../../conversation/Conversation'; import { MediaAsset } from '../../conversation/Conversation';

View File

@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { MediaAsset } from '../../conversation/Conversation'; import { MediaAsset } from '../../conversation/Conversation';
import { useBinaryAsset } from './useBinaryAsset.hook'; import { useBinaryAsset } from './useBinaryAsset.hook';
import { Progress, ActionIcon, Image } from '@mantine/core' import { Progress, ActionIcon, Image } from '@mantine/core'

View File

@ -1,6 +1,5 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useRef } from 'react'
import { AppContext } from '../../context/AppContext' import { AppContext } from '../../context/AppContext'
import { Focus } from 'databag-client-sdk'
import { ContextType } from '../../context/ContextType' import { ContextType } from '../../context/ContextType'
import { MediaAsset } from '../../conversation/Conversation'; import { MediaAsset } from '../../conversation/Conversation';

View File

@ -1,6 +1,5 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useEffect, useRef } from 'react'
import { AppContext } from '../../context/AppContext' import { AppContext } from '../../context/AppContext'
import { Focus } from 'databag-client-sdk'
import { ContextType } from '../../context/ContextType' import { ContextType } from '../../context/ContextType'
import { MediaAsset } from '../../conversation/Conversation'; import { MediaAsset } from '../../conversation/Conversation';

View File

@ -41,6 +41,7 @@ export function useMessage() {
await focus.removeTopic(topicId); await focus.removeTopic(topicId);
} }
}, },
// eslint-disable-next-line @typescript-eslint/no-explicit-any
saveSubject: async (topicId: string, sealed: boolean, subject: any) => { saveSubject: async (topicId: string, sealed: boolean, subject: any) => {
const focus = app.state.focus; const focus = app.state.focus;
if (focus) { if (focus) {

View File

@ -1,6 +1,5 @@
import { useState, useContext, useEffect, useRef} from 'react' import { useState, useContext, useEffect, useRef} from 'react'
import { AppContext } from '../../context/AppContext' import { AppContext } from '../../context/AppContext'
import { Focus } from 'databag-client-sdk'
import { ContextType } from '../../context/ContextType' import { ContextType } from '../../context/ContextType'
import { MediaAsset } from '../../conversation/Conversation'; import { MediaAsset } from '../../conversation/Conversation';

View File

@ -3,7 +3,6 @@ import { useProfile } from './useProfile.hook'
import classes from './Profile.module.css' import classes from './Profile.module.css'
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
import { import {
IconX,
IconMapPin, IconMapPin,
IconBook, IconBook,
IconUserX, IconUserX,

View File

@ -104,7 +104,7 @@ export function useProfile(params: ProfileParams) {
}, },
saveAndConnect: async () => { saveAndConnect: async () => {
const contact = app.state.session?.getContact(); const contact = app.state.session?.getContact();
const added = await contact.addAndConnectCard(state.node, state.guid); await contact.addAndConnectCard(state.node, state.guid);
}, },
remove: async () => { remove: async () => {
const contact = app.state.session?.getContact() const contact = app.state.session?.getContact()

View File

@ -61,7 +61,6 @@ export function useRegistry() {
identity.removeProfileListener(setProfile); identity.removeProfileListener(setProfile);
}; };
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
useEffect(() => { useEffect(() => {

View File

@ -5,8 +5,8 @@ import { Card as Contact } from '../card/Card';
import { Card } from 'databag-client-sdk'; import { Card } from 'databag-client-sdk';
import { Colors } from '../constants/Colors'; import { Colors } from '../constants/Colors';
import { modals } from '@mantine/modals' import { modals } from '@mantine/modals'
import { Loader, Image, Text, ActionIcon } from '@mantine/core' import { Loader, Text, ActionIcon } from '@mantine/core'
import { IconBell, IconVideoPlus, IconEyeX, IconPhone, IconPhoneOff, IconArrowsMaximize, IconMicrophone, IconMicrophoneOff } from '@tabler/icons-react' import { IconBell, IconVideoPlus, IconEyeX, IconPhone, IconArrowsMaximize, IconMicrophone, IconMicrophoneOff } from '@tabler/icons-react'
export function Ring() { export function Ring() {
const { state, actions } = useRing(); const { state, actions } = useRing();
@ -117,7 +117,7 @@ export function Ring() {
const acceptButton = <ActionIcon key="accept" variant="subtle" loading={accepting===ring.callId} onClick={()=>accept(callId, card)} color={Colors.primary}><IconPhone /></ActionIcon> const acceptButton = <ActionIcon key="accept" variant="subtle" loading={accepting===ring.callId} onClick={()=>accept(callId, card)} color={Colors.primary}><IconPhone /></ActionIcon>
return ( return (
<Contact className={classes.card} placeholder={''} imageUrl={imageUrl} name={name} node={node} handle={handle} actions={[ignoreButton, declineButton, acceptButton]} /> <Contact key={`ring-${index}`} className={classes.card} placeholder={''} imageUrl={imageUrl} name={name} node={node} handle={handle} actions={[ignoreButton, declineButton, acceptButton]} />
) )
}); });

View File

@ -1,7 +1,5 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { Text, Drawer } from '@mantine/core' import { Drawer } from '@mantine/core'
import { DisplayContext } from '../context/DisplayContext'
import { ContextType } from '../context/ContextType'
import classes from './Service.module.css' import classes from './Service.module.css'
import { useService } from './useService.hook' import { useService } from './useService.hook'
import { IconAddressBook, IconSettings } from '@tabler/icons-react' import { IconAddressBook, IconSettings } from '@tabler/icons-react'

View File

@ -1,4 +1,4 @@
import {useEffect, useState, useContext, useRef} from 'react'; import {useEffect, useState, useContext} from 'react';
import {AppContext} from '../context/AppContext'; import {AppContext} from '../context/AppContext';
import {DisplayContext} from '../context/DisplayContext'; import {DisplayContext} from '../context/DisplayContext';
import {ContextType} from '../context/ContextType'; import {ContextType} from '../context/ContextType';
@ -12,6 +12,7 @@ export function useService() {
strings: {}, strings: {},
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateState = (value: any) => { const updateState = (value: any) => {
setState(s => ({...s, ...value})); setState(s => ({...s, ...value}));
}; };

View File

@ -1,8 +1,6 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { Text, Drawer } from '@mantine/core' import { Text, Drawer } from '@mantine/core'
import { DisplayContext } from '../context/DisplayContext'
import { RingContextProvider } from '../context/RingContext' import { RingContextProvider } from '../context/RingContext'
import { ContextType } from '../context/ContextType'
import classes from './Session.module.css' import classes from './Session.module.css'
import { useSession } from './useSession.hook' import { useSession } from './useSession.hook'
import { IconAddressBook, IconMessages, IconSettings } from '@tabler/icons-react' import { IconAddressBook, IconMessages, IconSettings } from '@tabler/icons-react'
@ -14,7 +12,6 @@ import { Profile, ProfileParams } from '../profile/Profile'
import { Details } from '../details/Details'; import { Details } from '../details/Details';
import { Content } from '../content/Content' import { Content } from '../content/Content'
import { Conversation } from '../conversation/Conversation' import { Conversation } from '../conversation/Conversation'
import { Focus, Card } from 'databag-client-sdk'
import { useDisclosure } from '@mantine/hooks' import { useDisclosure } from '@mantine/hooks'
import { IconAlertCircle } from '@tabler/icons-react' import { IconAlertCircle } from '@tabler/icons-react'
import { Base } from '../base/Base'; import { Base } from '../base/Base';

View File

@ -1,4 +1,4 @@
import { useState, useContext, useEffect, useRef } from 'react' import { useState, useContext, useEffect } from 'react'
import { AppContext } from '../context/AppContext' import { AppContext } from '../context/AppContext'
import { DisplayContext } from '../context/DisplayContext' import { DisplayContext } from '../context/DisplayContext'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'

View File

@ -2,7 +2,7 @@ import { useEffect, useState, useContext, useRef } from 'react'
import { AppContext } from '../context/AppContext' import { AppContext } from '../context/AppContext'
import { DisplayContext } from '../context/DisplayContext' import { DisplayContext } from '../context/DisplayContext'
import { ContextType } from '../context/ContextType' import { ContextType } from '../context/ContextType'
import { type Profile, type Config, type PushParams, PushType } from 'databag-client-sdk' import { type Profile, type Config, PushType } from 'databag-client-sdk'
import { Point, Area } from 'react-easy-crop/types' import { Point, Area } from 'react-easy-crop/types'
const IMAGE_DIM = 192 const IMAGE_DIM = 192
@ -17,7 +17,7 @@ function urlB64ToUint8Array(b64: string) {
const rawData = window.atob(base64); const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length); const outputArray = new Uint8Array(rawData.length);
for (var i = 0; i < rawData.length; ++i) { for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i); outputArray[i] = rawData.charCodeAt(i);
} }
return outputArray; return outputArray;

View File

@ -1,8 +1,7 @@
import { useState } from 'react' import React, { useState } from 'react'
import classes from './Setup.module.css' import classes from './Setup.module.css'
import { useSetup } from './useSetup.hook' import { useSetup } from './useSetup.hook'
import { PinInput, Image, Button, Radio, Group, Loader, Modal, Divider, Text, TextInput, Switch, ActionIcon } from '@mantine/core' import { PinInput, Image, Button, Radio, Group, Loader, Modal, Divider, Text, TextInput, Switch, ActionIcon } from '@mantine/core'
import { modals } from '@mantine/modals'
import { useDisclosure } from '@mantine/hooks' import { useDisclosure } from '@mantine/hooks'
import { IconCheck, IconLogout, IconCopy } from '@tabler/icons-react' import { IconCheck, IconLogout, IconCopy } from '@tabler/icons-react'

View File

@ -30,6 +30,7 @@ export function useSetup() {
confirmMFAuthImage: '', confirmMFAuthImage: '',
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const updateState = (value: any) => { const updateState = (value: any) => {
setState(s => ({...s, ...value})); setState(s => ({...s, ...value}));
}; };