mirror of
https://github.com/balzack/databag.git
synced 2025-03-13 00:50:03 +00:00
187 lines
4.5 KiB
JavaScript
187 lines
4.5 KiB
JavaScript
import { useState, useEffect, useRef, useContext } from 'react';
|
|
import { useWindowDimensions } from 'react-native';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { CardContext } from 'context/CardContext';
|
|
import { ChannelContext } from 'context/ChannelContext';
|
|
import { ProfileContext } from 'context/ProfileContext';
|
|
import { AppContext } from 'context/AppContext';
|
|
import config from 'constants/Config';
|
|
|
|
export function useChannels() {
|
|
|
|
const [state, setState] = useState({
|
|
topic: null,
|
|
channels: [],
|
|
tabbed: null,
|
|
filter: null,
|
|
});
|
|
|
|
const items = useRef([]);
|
|
const channel = useContext(ChannelContext);
|
|
const card = useContext(CardContext);
|
|
const profile = useContext(ProfileContext);
|
|
const app = useContext(AppContext);
|
|
const dimensions = useWindowDimensions();
|
|
|
|
const updateState = (value) => {
|
|
setState((s) => ({ ...s, ...value }));
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (dimensions.width > config.tabbedWidth) {
|
|
updateState({ tabbed: false });
|
|
}
|
|
else {
|
|
updateState({ tabbed: true });
|
|
}
|
|
}, [dimensions]);
|
|
|
|
const getCard = (guid) => {
|
|
let contact = null
|
|
card.state.cards.forEach((card, cardId, map) => {
|
|
if (card?.profile?.guid === guid) {
|
|
contact = card;
|
|
}
|
|
});
|
|
return contact;
|
|
}
|
|
|
|
const setChannelEntry = (item) => {
|
|
|
|
let updated = false;
|
|
const login = app.state.loginTimestamp;
|
|
const update = item?.summary?.lastTopic?.created;
|
|
if (update && login && login < update) {
|
|
if (!item.readRevision || item.readRevision < item.revision) {
|
|
updated = true;
|
|
}
|
|
}
|
|
|
|
let contacts = [];
|
|
if (item.cardId) {
|
|
contacts.push(card.state.cards.get(item.cardId));
|
|
}
|
|
if (item?.detail?.members) {
|
|
|
|
item.detail.members.forEach(guid => {
|
|
const profileGuid = profile.state.profile.guid;
|
|
if (profileGuid !== guid) {
|
|
contacts.push(getCard(guid));
|
|
}
|
|
})
|
|
}
|
|
|
|
let logo = null;
|
|
if (contacts.length === 0) {
|
|
logo = 'solution';
|
|
}
|
|
else if (contacts.length === 1) {
|
|
if (contacts[0]?.profile?.imageSet) {
|
|
logo = card.actions.getCardLogo(contacts[0].cardId, contacts[0].profileRevision);
|
|
}
|
|
else {
|
|
logo = 'avatar';
|
|
}
|
|
}
|
|
else {
|
|
logo = 'appstore';
|
|
}
|
|
|
|
let subject = null;
|
|
if (item?.detail?.data) {
|
|
try {
|
|
subject = JSON.parse(item?.detail?.data).subject;
|
|
}
|
|
catch (err) {
|
|
console.log(err);
|
|
}
|
|
}
|
|
if (!subject) {
|
|
if (contacts.length) {
|
|
let names = [];
|
|
for (let contact of contacts) {
|
|
if (contact?.profile?.name) {
|
|
names.push(contact.profile.name);
|
|
}
|
|
else if (contact?.profile?.handle) {
|
|
names.push(contact?.profile?.handle);
|
|
}
|
|
}
|
|
subject = names.join(', ');
|
|
}
|
|
else {
|
|
subject = "Notes";
|
|
}
|
|
}
|
|
|
|
let message;
|
|
if (item?.summary?.lastTopic?.dataType === 'superbasictopic') {
|
|
try {
|
|
message = JSON.parse(item.summary.lastTopic.data).text;
|
|
}
|
|
catch (err) {
|
|
console.log(err);
|
|
}
|
|
}
|
|
|
|
const timestamp = item?.summary?.lastTopic?.created;
|
|
|
|
return { cardId: item.cardId, channelId: item.channelId, contacts, logo, subject, message, updated, revision: item.revision, timestamp, blocked: item.blocked === 1 };
|
|
}
|
|
|
|
useEffect(() => {
|
|
let merged = [];
|
|
card.state.cards.forEach((card, cardId, map) => {
|
|
if (!card.blocked) {
|
|
merged.push(...Array.from(card.channels.values()));
|
|
}
|
|
});
|
|
merged.push(...Array.from(channel.state.channels.values()));
|
|
|
|
const items = merged.map(setChannelEntry);
|
|
|
|
const filtered = items.filter(item => {
|
|
if (item.blocked === true) {
|
|
return false;
|
|
}
|
|
|
|
if (!state.filter) {
|
|
return true;
|
|
}
|
|
const lower = state.filter.toLowerCase();
|
|
if (item.subject) {
|
|
if (item.subject.toLowerCase().includes(lower)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
|
|
const sorted = filtered.sort((a, b) => {
|
|
const aCreated = a?.timestamp;
|
|
const bCreated = b?.timestamp;
|
|
if (aCreated === bCreated) {
|
|
return 0;
|
|
}
|
|
if (!aCreated || aCreated < bCreated) {
|
|
return 1;
|
|
}
|
|
return -1;
|
|
});
|
|
|
|
updateState({ channels: sorted });
|
|
}, [channel, card, state.filter]);
|
|
|
|
const actions = {
|
|
setTopic: (topic) => {
|
|
updateState({ topic });
|
|
},
|
|
setFilter: (filter) => {
|
|
updateState({ filter });
|
|
},
|
|
};
|
|
|
|
return { state, actions };
|
|
}
|
|
|