From a53a3d4847a24192e1d1b2ff19eb6314ba861823 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Tue, 24 May 2022 15:21:12 -0700 Subject: [PATCH] allow for channel membership to change --- net/server/internal/api_clearChannelCard.go | 2 +- net/server/internal/api_setChannelCard.go | 2 +- .../Members/MemberItem/useMemberItem.hook.js | 8 ++++--- .../Conversation/Members/Members.styled.jsx | 2 +- .../Conversation/Members/useMembers.hook.js | 21 +++++++++++++++++++ .../SideBar/Contacts/Cards/useCards.hook.js | 21 ++++++++++++++++++- net/web/src/api/clearChannelCard.js | 7 +++++++ net/web/src/api/setChannelCard.js | 7 +++++++ net/web/src/context/useChannelContext.hook.js | 8 +++++++ .../context/useConversationContext.hook.js | 6 ++++++ 10 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 net/web/src/api/clearChannelCard.js create mode 100644 net/web/src/api/setChannelCard.js diff --git a/net/server/internal/api_clearChannelCard.go b/net/server/internal/api_clearChannelCard.go index 241f6be2..20fd0f7d 100644 --- a/net/server/internal/api_clearChannelCard.go +++ b/net/server/internal/api_clearChannelCard.go @@ -10,7 +10,7 @@ import ( func ClearChannelCard(w http.ResponseWriter, r *http.Request) { - account, code, err := BearerAppToken(r, false); + account, code, err := ParamAgentToken(r, false); if err != nil { ErrResponse(w, code, err) return diff --git a/net/server/internal/api_setChannelCard.go b/net/server/internal/api_setChannelCard.go index cdb10e96..abc85594 100644 --- a/net/server/internal/api_setChannelCard.go +++ b/net/server/internal/api_setChannelCard.go @@ -10,7 +10,7 @@ import ( func SetChannelCard(w http.ResponseWriter, r *http.Request) { - account, code, err := BearerAppToken(r, false); + account, code, err := ParamAgentToken(r, false); if err != nil { ErrResponse(w, code, err) return diff --git a/net/web/src/User/Conversation/Members/MemberItem/useMemberItem.hook.js b/net/web/src/User/Conversation/Members/MemberItem/useMemberItem.hook.js index 3ec69523..71d73e65 100644 --- a/net/web/src/User/Conversation/Members/MemberItem/useMemberItem.hook.js +++ b/net/web/src/User/Conversation/Members/MemberItem/useMemberItem.hook.js @@ -1,5 +1,6 @@ import { useContext, useState, useEffect, useRef } from 'react'; import { CardContext } from 'context/CardContext'; +import { ConversationContext } from 'context/ConversationContext'; export function useMemberItem({ item }) { @@ -10,10 +11,11 @@ export function useMemberItem({ item }) { }); const card = useContext(CardContext); + const conversation = useContext(ConversationContext); useEffect(() => { updateState({ - imageUrl: card.actions.getImageUrl(item.card.id), + imageUrl: card.actions.getImageUrl(item.card?.id), name: item.card?.data.cardProfile.name, handle: item.card?.data.cardProfile.handle, }); @@ -25,10 +27,10 @@ export function useMemberItem({ item }) { const actions = { setMembership: async () => { - console.log("set membership"); + conversation.actions.setChannelCard(item.card.id); }, clearMembership: async () => { - console.log("clear membership"); + conversation.actions.clearChannelCard(item.card.id); }, }; diff --git a/net/web/src/User/Conversation/Members/Members.styled.jsx b/net/web/src/User/Conversation/Members/Members.styled.jsx index 85b2b76f..8e5e0854 100644 --- a/net/web/src/User/Conversation/Members/Members.styled.jsx +++ b/net/web/src/User/Conversation/Members/Members.styled.jsx @@ -2,7 +2,7 @@ import styled from 'styled-components'; export const MembersWrapper = styled.div` width: 100%; - height: 240px; + max-height: 240px; background-color: #f6f5ed; overflow: auto; `; diff --git a/net/web/src/User/Conversation/Members/useMembers.hook.js b/net/web/src/User/Conversation/Members/useMembers.hook.js index 2648140f..47545962 100644 --- a/net/web/src/User/Conversation/Members/useMembers.hook.js +++ b/net/web/src/User/Conversation/Members/useMembers.hook.js @@ -31,6 +31,27 @@ export function useMembers({ host, members }) { contacts.push({ member: members.has(value.data.cardProfile.guid), card: value }); }); } + + contacts.sort((a, b) => { + let aName = a.card?.data?.cardProfile?.name?.toLowerCase(); + let bName = b.card?.data?.cardProfile?.name?.toLowerCase(); + if (aName == null && bName == null) { + return 0; + } + if (aName == null && bName != null) { + return 1; + } + if (aName != null && bName == null) { + return -1; + } + if (aName < bName) { + return -1; + } + if (aName > bName) { + return 1; + } + return 0; + }); updateState({ readonly, contacts }); }, [host, members]); diff --git a/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js b/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js index d68b998b..065ed933 100644 --- a/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js +++ b/net/web/src/User/SideBar/Contacts/Cards/useCards.hook.js @@ -23,7 +23,26 @@ export function useCards() { } useEffect(() => { - updateState({ cards: Array.from(card.state.cards.values()) }); + updateState({ cards: Array.from(card.state.cards.values()).sort((a, b) => { + let aName = a.data?.cardProfile?.name?.toLowerCase(); + let bName = b.data?.cardProfile?.name?.toLowerCase(); + if (aName == null && bName == null) { + return 0; + } + if (aName == null && bName != null) { + return 1; + } + if (aName != null && bName == null) { + return -1; + } + if (aName < bName) { + return -1; + } + if (aName > bName) { + return 1; + } + return 0; + })}); }, [card]) return { state, actions }; diff --git a/net/web/src/api/clearChannelCard.js b/net/web/src/api/clearChannelCard.js new file mode 100644 index 00000000..7e182fe9 --- /dev/null +++ b/net/web/src/api/clearChannelCard.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function clearChannelCard(token, channelId, cardId ) { + let channel = await fetchWithTimeout(`/content/channels/${channelId}/cards/${cardId}?agent=${token}`, {method: 'DELETE'}); + checkResponse(channel); + return await channel.json(); +} diff --git a/net/web/src/api/setChannelCard.js b/net/web/src/api/setChannelCard.js new file mode 100644 index 00000000..c9da3287 --- /dev/null +++ b/net/web/src/api/setChannelCard.js @@ -0,0 +1,7 @@ +import { checkResponse, fetchWithTimeout } from './fetchUtil'; + +export async function setChannelCard(token, channelId, cardId ) { + let channel = await fetchWithTimeout(`/content/channels/${channelId}/cards/${cardId}?agent=${token}`, {method: 'PUT'}); + checkResponse(channel); + return await channel.json(); +} diff --git a/net/web/src/context/useChannelContext.hook.js b/net/web/src/context/useChannelContext.hook.js index cd0905a2..9790bbb6 100644 --- a/net/web/src/context/useChannelContext.hook.js +++ b/net/web/src/context/useChannelContext.hook.js @@ -9,6 +9,8 @@ import { getChannelTopics } from 'api/getChannelTopics'; import { getChannelTopic } from 'api/getChannelTopic'; import { getChannelTopicAssetUrl } from 'api/getChannelTopicAssetUrl'; import { setChannelSubject } from 'api/setChannelSubject'; +import { setChannelCard } from 'api/setChannelCard'; +import { clearChannelCard } from 'api/clearChannelCard'; export function useChannelContext() { const [state, setState] = useState({ init: false, @@ -98,6 +100,12 @@ export function useChannelContext() { setChannelSubject: async (channelId, subject) => { return await setChannelSubject(access.current, channelId, subject); }, + setChannelCard: async (channelId, cardId) => { + return await setChannelCard(access.current, channelId, cardId); + }, + clearChannelCard: async (channelId, cardId) => { + return await clearChannelCard(access.current, channelId, cardId); + }, removeChannel: async (channelId) => { return await removeChannel(access.current, channelId); }, diff --git a/net/web/src/context/useConversationContext.hook.js b/net/web/src/context/useConversationContext.hook.js index cfc6dc90..1fe86005 100644 --- a/net/web/src/context/useConversationContext.hook.js +++ b/net/web/src/context/useConversationContext.hook.js @@ -223,6 +223,12 @@ export function useConversationContext() { setChannelSubject: async (subject) => { return await channel.actions.setChannelSubject(conversationId.current.channelId, subject); }, + setChannelCard: async (cardId) => { + return await channel.actions.setChannelCard(conversationId.current.channelId, cardId); + }, + clearChannelCard: async (cardId) => { + return await channel.actions.clearChannelCard(conversationId.current.channelId, cardId); + }, getAssetUrl: (topicId, assetId) => { const { cardId, channelId } = conversationId.current; if (conversationId.current.cardId) {