From 58a2984dbcd6b8332835abafda956fb40316bdf3 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Thu, 1 Sep 2022 00:22:43 -0700 Subject: [PATCH] providing server side config for key size and asset type support --- doc/api.oa3 | 19 +++++--- net/server/internal/api_addChannel.go | 6 ++- net/server/internal/api_clearChannelCard.go | 6 ++- net/server/internal/api_clearChannelGroup.go | 6 ++- .../internal/api_getAccountAvailable.go | 4 +- net/server/internal/api_getChannelDetail.go | 8 +++- net/server/internal/api_getChannels.go | 8 +++- net/server/internal/api_getNodeConfig.go | 6 ++- net/server/internal/api_setChannelCard.go | 6 ++- net/server/internal/api_setChannelGroup.go | 6 ++- net/server/internal/api_setChannelSubject.go | 6 ++- net/server/internal/api_setNodeConfig.go | 48 ++++++++++++------- net/server/internal/configUtil.go | 12 +++++ net/server/internal/keyUtil.go | 16 ++----- net/server/internal/modelUtil.go | 9 ++-- net/server/internal/models.go | 14 +++++- net/web/src/admin/dashboard/Dashboard.jsx | 32 ++++++++++--- .../src/admin/dashboard/Dashboard.styled.js | 9 +--- .../src/admin/dashboard/useDashboard.hook.js | 42 +++++++++++----- .../context/useConversationContext.hook.js | 7 +++ .../conversation/addTopic/AddTopic.jsx | 24 ++++++---- .../conversation/addTopic/useAddTopic.hook.js | 12 ++++- 22 files changed, 217 insertions(+), 89 deletions(-) diff --git a/doc/api.oa3 b/doc/api.oa3 index 1f35bd8f..a369ea0e 100644 --- a/doc/api.oa3 +++ b/doc/api.oa3 @@ -3271,8 +3271,6 @@ components: type: object required: - domain - - openAccess - - accountLimit - accountStorage properties: domain: @@ -3280,11 +3278,14 @@ components: accountStorage: type: integer format: int64 - openAccess: + enableImage: type: boolean - accountLimit: - type: integer - format: int64 + enableAudio: + type: boolean + enableVideo: + type: boolean + keyType: + type: string AccountStatus: type: object @@ -3627,6 +3628,12 @@ components: updated: type: integer format: int64 + enableImage: + type: boolean + enableAudio: + type: boolean + enableVideo: + type: video contacts: $ref: '#/components/schemas/ChannelContacts' members: diff --git a/net/server/internal/api_addChannel.go b/net/server/internal/api_addChannel.go index 7b8440a2..92684043 100644 --- a/net/server/internal/api_addChannel.go +++ b/net/server/internal/api_addChannel.go @@ -80,5 +80,9 @@ func AddChannel(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, card) } - WriteResponse(w, getChannelModel(slot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(slot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_clearChannelCard.go b/net/server/internal/api_clearChannelCard.go index 736b4239..5e7a8296 100644 --- a/net/server/internal/api_clearChannelCard.go +++ b/net/server/internal/api_clearChannelCard.go @@ -89,5 +89,9 @@ func ClearChannelCard(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, &card) } - WriteResponse(w, getChannelModel(&channelSlot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_clearChannelGroup.go b/net/server/internal/api_clearChannelGroup.go index 613c2ce9..3baf26bf 100644 --- a/net/server/internal/api_clearChannelGroup.go +++ b/net/server/internal/api_clearChannelGroup.go @@ -83,5 +83,9 @@ func ClearChannelGroup(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, &card) } - WriteResponse(w, getChannelModel(&channelSlot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_getAccountAvailable.go b/net/server/internal/api_getAccountAvailable.go index cd5e4b2c..57621269 100644 --- a/net/server/internal/api_getAccountAvailable.go +++ b/net/server/internal/api_getAccountAvailable.go @@ -19,8 +19,8 @@ func GetAccountAvailable(w http.ResponseWriter, r *http.Request) { func getAvailableAccounts() (available int64, err error) { - open := getBoolConfigValue(CNFOpenAccess, true) - limit := getNumConfigValue(CNFAccountLimit, 16) + open := getBoolConfigValue(CNFOpenAccess, false) + limit := getNumConfigValue(CNFAccountLimit, 0) var count int64 if err = store.DB.Model(&store.Account{}).Count(&count).Error; err != nil { diff --git a/net/server/internal/api_getChannelDetail.go b/net/server/internal/api_getChannelDetail.go index f9f8f09d..9e646e04 100644 --- a/net/server/internal/api_getChannelDetail.go +++ b/net/server/internal/api_getChannelDetail.go @@ -49,15 +49,19 @@ func GetChannelDetail(w http.ResponseWriter, r *http.Request) { return } + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + // return model data if guid != "" { if isChannelShared(guid, slot.Channel) { - WriteResponse(w, getChannelDetailModel(&slot, false)) + WriteResponse(w, getChannelDetailModel(&slot, false, image, audio, video)) } else { ErrResponse(w, http.StatusNotFound, errors.New("channel not shared with requestor")) return } } else { - WriteResponse(w, getChannelDetailModel(&slot, true)) + WriteResponse(w, getChannelDetailModel(&slot, true, image, audio, video)) } } diff --git a/net/server/internal/api_getChannels.go b/net/server/internal/api_getChannels.go index 90568c10..d123f74a 100644 --- a/net/server/internal/api_getChannels.go +++ b/net/server/internal/api_getChannels.go @@ -50,6 +50,10 @@ func GetChannels(w http.ResponseWriter, r *http.Request) { } } + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + response := []*Channel{} tokenType := ParamTokenType(r) if tokenType == APPTokenAgent { @@ -80,7 +84,7 @@ func GetChannels(w http.ResponseWriter, r *http.Request) { if channelRevisionSet { response = append(response, getChannelRevisionModel(&slot, true)) } else if slot.Channel != nil { - response = append(response, getChannelModel(&slot, true, true)) + response = append(response, getChannelModel(&slot, true, true, image, audio, video)) } } } @@ -124,7 +128,7 @@ func GetChannels(w http.ResponseWriter, r *http.Request) { if channelRevisionSet { response = append(response, getChannelRevisionModel(&slot, shared)) } else if shared { - response = append(response, getChannelModel(&slot, true, false)) + response = append(response, getChannelModel(&slot, true, false, image, audio, video)) } } } diff --git a/net/server/internal/api_getNodeConfig.go b/net/server/internal/api_getNodeConfig.go index 2bee9ca9..a657b734 100644 --- a/net/server/internal/api_getNodeConfig.go +++ b/net/server/internal/api_getNodeConfig.go @@ -16,9 +16,11 @@ func GetNodeConfig(w http.ResponseWriter, r *http.Request) { // get node config fields var config NodeConfig config.Domain = getStrConfigValue(CNFDomain, "") - config.AccountLimit = getNumConfigValue(CNFAccountLimit, 16) - config.OpenAccess = getBoolConfigValue(CNFOpenAccess, true) config.AccountStorage = getNumConfigValue(CNFStorage, 0) + config.EnableImage = getBoolConfigValue(CNFEnableImage, true) + config.EnableAudio = getBoolConfigValue(CNFEnableAudio, true) + config.EnableVideo = getBoolConfigValue(CNFEnableVideo, true) + config.KeyType = getStrConfigValue(CNFKeyType, APPRSA4096) WriteResponse(w, config) } diff --git a/net/server/internal/api_setChannelCard.go b/net/server/internal/api_setChannelCard.go index 41128af6..cf573aa8 100644 --- a/net/server/internal/api_setChannelCard.go +++ b/net/server/internal/api_setChannelCard.go @@ -90,5 +90,9 @@ func SetChannelCard(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, &card) } - WriteResponse(w, getChannelModel(&channelSlot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_setChannelGroup.go b/net/server/internal/api_setChannelGroup.go index 162110f8..3629b198 100644 --- a/net/server/internal/api_setChannelGroup.go +++ b/net/server/internal/api_setChannelGroup.go @@ -83,5 +83,9 @@ func SetChannelGroup(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, &card) } - WriteResponse(w, getChannelModel(&channelSlot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(&channelSlot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_setChannelSubject.go b/net/server/internal/api_setChannelSubject.go index d5c5f381..d12ff3b8 100644 --- a/net/server/internal/api_setChannelSubject.go +++ b/net/server/internal/api_setChannelSubject.go @@ -82,5 +82,9 @@ func SetChannelSubject(w http.ResponseWriter, r *http.Request) { for _, card := range cards { SetContactChannelNotification(account, &card) } - WriteResponse(w, getChannelModel(&slot, true, true)) + + video := getBoolConfigValue(CNFEnableVideo, true); + audio := getBoolConfigValue(CNFEnableAudio, true); + image := getBoolConfigValue(CNFEnableImage, true); + WriteResponse(w, getChannelModel(&slot, true, true, image, audio, video)) } diff --git a/net/server/internal/api_setNodeConfig.go b/net/server/internal/api_setNodeConfig.go index dcaf4836..8691539f 100644 --- a/net/server/internal/api_setNodeConfig.go +++ b/net/server/internal/api_setNodeConfig.go @@ -34,22 +34,6 @@ func SetNodeConfig(w http.ResponseWriter, r *http.Request) { return res } - // upsert account limit config - if res := tx.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "config_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"num_value"}), - }).Create(&store.Config{ConfigID: CNFAccountLimit, NumValue: config.AccountLimit}).Error; res != nil { - return res - } - - // upsert account open access - if res := tx.Clauses(clause.OnConflict{ - Columns: []clause.Column{{Name: "config_id"}}, - DoUpdates: clause.AssignmentColumns([]string{"bool_value"}), - }).Create(&store.Config{ConfigID: CNFAccountLimit, BoolValue: config.OpenAccess}).Error; res != nil { - return res - } - // upsert account storage config if res := tx.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "config_id"}}, @@ -58,6 +42,38 @@ func SetNodeConfig(w http.ResponseWriter, r *http.Request) { return res } + // upsert enable image processing + if res := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "config_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"bool_value"}), + }).Create(&store.Config{ConfigID: CNFEnableImage, BoolValue: config.EnableImage}).Error; res != nil { + return res + } + + // upsert enable audio processing + if res := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "config_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"bool_value"}), + }).Create(&store.Config{ConfigID: CNFEnableAudio, BoolValue: config.EnableAudio}).Error; res != nil { + return res + } + + // upsert enable video processing + if res := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "config_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"bool_value"}), + }).Create(&store.Config{ConfigID: CNFEnableVideo, BoolValue: config.EnableVideo}).Error; res != nil { + return res + } + + // upsert key type + if res := tx.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "config_id"}}, + DoUpdates: clause.AssignmentColumns([]string{"str_value"}), + }).Create(&store.Config{ConfigID: CNFKeyType, StrValue: config.KeyType}).Error; res != nil { + return res + } + return nil }) if err != nil { diff --git a/net/server/internal/configUtil.go b/net/server/internal/configUtil.go index 1433626c..d26b70d1 100644 --- a/net/server/internal/configUtil.go +++ b/net/server/internal/configUtil.go @@ -30,6 +30,18 @@ const CNFAssetPath = "asset_path" //CNFScriptPath specifies the path where transform scripts are found const CNFScriptPath = "script_path" +//CNFEnableImage specifies whether node can process image assets +const CNFEnableImage = "enable_image" + +//CNFEnableAudio specifies whether node can process audio assets +const CNFEnableAudio = "enable_audio" + +//CNFEnableVideo specifies whether node can process video assets +const CNFEnableVideo = "enable_video" + +//CNFKeyType specifies the type of key to use for identity +const CNFKeyType = "key_type" + func getStrConfigValue(configID string, empty string) string { var config store.Config err := store.DB.Where("config_id = ?", configID).First(&config).Error diff --git a/net/server/internal/keyUtil.go b/net/server/internal/keyUtil.go index 6fcb835f..b7287b50 100644 --- a/net/server/internal/keyUtil.go +++ b/net/server/internal/keyUtil.go @@ -8,20 +8,14 @@ import ( "errors" ) -var keySize int = APPKeySize - -//SetKeySize sets the key size to use for new accounts -func SetKeySize(size int) { - keySize = size -} - //GenerateRsaKeyPair creates a public/private key for a new account func GenerateRsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey, string, error) { - if keySize == 2048 { - privkey, _ := rsa.GenerateKey(rand.Reader, keySize) + keyType := getStrConfigValue(CNFKeyType, "RSA4096"); + if keyType == "RSA2048" { + privkey, _ := rsa.GenerateKey(rand.Reader, 2048) return privkey, &privkey.PublicKey, "RSA2048", nil - } else if keySize == 4096 { - privkey, _ := rsa.GenerateKey(rand.Reader, keySize) + } else if keyType == "RSA4096" { + privkey, _ := rsa.GenerateKey(rand.Reader, 4096) return privkey, &privkey.PublicKey, "RSA2048", nil } else { return nil, nil, "", errors.New("invalid key setting") diff --git a/net/server/internal/modelUtil.go b/net/server/internal/modelUtil.go index 0f949cc8..50e66d44 100644 --- a/net/server/internal/modelUtil.go +++ b/net/server/internal/modelUtil.go @@ -166,7 +166,7 @@ func getChannelRevisionModel(slot *store.ChannelSlot, showData bool) *Channel { } } -func getChannelDetailModel(slot *store.ChannelSlot, showList bool) *ChannelDetail { +func getChannelDetailModel(slot *store.ChannelSlot, showList bool, image bool, audio bool, video bool) *ChannelDetail { if slot.Channel == nil { return nil @@ -195,6 +195,9 @@ func getChannelDetailModel(slot *store.ChannelSlot, showList bool) *ChannelDetai Data: slot.Channel.Data, Created: slot.Channel.Created, Updated: slot.Channel.Updated, + EnableImage: image, + EnableAudio: audio, + EnableVideo: video, Contacts: contacts, Members: members, } @@ -221,7 +224,7 @@ func getChannelSummaryModel(slot *store.ChannelSlot) *ChannelSummary { } } -func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool) *Channel { +func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool, image bool, audio bool, video bool) *Channel { if !showData || slot.Channel == nil { return &Channel{ @@ -236,7 +239,7 @@ func getChannelModel(slot *store.ChannelSlot, showData bool, showList bool) *Cha Data: &ChannelData{ DetailRevision: slot.Channel.DetailRevision, TopicRevision: slot.Channel.TopicRevision, - ChannelDetail: getChannelDetailModel(slot, showList), + ChannelDetail: getChannelDetailModel(slot, showList, image, audio, video), ChannelSummary: getChannelSummaryModel(slot), }, } diff --git a/net/server/internal/models.go b/net/server/internal/models.go index 898ab842..ceac4df9 100644 --- a/net/server/internal/models.go +++ b/net/server/internal/models.go @@ -178,6 +178,12 @@ type ChannelDetail struct { Updated int64 `json:"updated"` + EnableImage bool `json:"enableImage"` + + EnableAudio bool `json:"enableAudio"` + + EnableVideo bool `json:"enableVideo"` + Contacts *ChannelContacts `json:"contacts,omitempty"` Members []string `json:"members"` @@ -321,9 +327,13 @@ type LoginAccess struct { type NodeConfig struct { Domain string `json:"domain"` - OpenAccess bool `json:"openAccess"` + EnableImage bool `json:"enableImage"` - AccountLimit int64 `json:"accountLimit"` + EnableAudio bool `json:"enableAudio"` + + EnableVideo bool `json:"enableVideo"` + + KeyType string `json:"keyType"` AccountStorage int64 `json:"accountStorage"` } diff --git a/net/web/src/admin/dashboard/Dashboard.jsx b/net/web/src/admin/dashboard/Dashboard.jsx index 8dac58f0..37d1a8cf 100644 --- a/net/web/src/admin/dashboard/Dashboard.jsx +++ b/net/web/src/admin/dashboard/Dashboard.jsx @@ -1,5 +1,5 @@ import { DashboardWrapper, SettingsButton, AddButton, SettingsLayout, CreateLayout } from './Dashboard.styled'; -import { Tooltip, Button, Modal, Input, InputNumber, Space, List } from 'antd'; +import { Tooltip, Checkbox, Select, Button, Modal, Input, InputNumber, Space, List } from 'antd'; import { SettingOutlined, CopyOutlined, UserAddOutlined, LogoutOutlined, ReloadOutlined } from '@ant-design/icons'; import { useDashboard } from './useDashboard.hook'; import { AccountItem } from './accountItem/AccountItem'; @@ -63,15 +63,35 @@ export function Dashboard({ token, config, logout }) { actions.setSettings()} onCancel={() => actions.setShowSettings(false)}> -
+
Federated Host: 
actions.setHost(e.target.value)} - value={state.host} /> + value={state.domain} />
-
+
Storage Limit (GB) / Account: 
- actions.setStorage(e)} - placeholder="0 for unrestricted" value={state.storage} /> + actions.setStorage(e)} + placeholder="0 for unrestricted" value={state.accountStorage} /> +
+
+
Account Key Type: 
+ +
+
+ actions.setEnableImage(e.target.checked)} + defaultChecked={true} checked={state.enableImage}>Enable Image Queue +
+
+ actions.setEnableAudio(e.target.checked)} + defaultChecked={true} checked={state.enableAudio}>Enable Audio Queue +
+
+ actions.setEnableVideo(e.target.checked)} + defaultChecked={true} checked={state.enableVideo}>Enable Video Queue
diff --git a/net/web/src/admin/dashboard/Dashboard.styled.js b/net/web/src/admin/dashboard/Dashboard.styled.js index 5ebb95ad..c59c4bad 100644 --- a/net/web/src/admin/dashboard/Dashboard.styled.js +++ b/net/web/src/admin/dashboard/Dashboard.styled.js @@ -71,14 +71,7 @@ export const SettingsButton = styled(Button)` export const SettingsLayout = styled(Space)` width: 100%; - .host { - white-space: nowrap; - display: flex; - flex-direction: row; - align-items: center; - } - - .storage { + .field { white-space: nowrap; display: flex; flex-direction: row; diff --git a/net/web/src/admin/dashboard/useDashboard.hook.js b/net/web/src/admin/dashboard/useDashboard.hook.js index 65e46156..d89ed8ff 100644 --- a/net/web/src/admin/dashboard/useDashboard.hook.js +++ b/net/web/src/admin/dashboard/useDashboard.hook.js @@ -7,8 +7,12 @@ import { addAccountCreate } from 'api/addAccountCreate'; export function useDashboard(token, config) { const [state, setState] = useState({ - host: "", - storage: null, + domain: "", + accountStorage: null, + keyType: null, + enableImage: null, + enableAudio: null, + enableVideo: null, showSettings: false, busy: false, loading: false, @@ -42,11 +46,23 @@ export function useDashboard(token, config) { await removeAccount(token, accountId); actions.getAccounts(); }, - setHost: (value) => { - updateState({ host: value }); + setHost: (domain) => { + updateState({ domain }); }, - setStorage: (value) => { - updateState({ storage: value }); + setStorage: (accountStorage) => { + updateState({ accountStorage }); + }, + setKeyType: (keyType) => { + updateState({ keyType }); + }, + setEnableImage: (enableImage) => { + updateState({ enableImage }); + }, + setEnableAudio: (enableAudio) => { + updateState({ enableAudio }); + }, + setEnableVideo: (enableVideo) => { + updateState({ enableVideo }); }, setShowSettings: (value) => { updateState({ showSettings: value }); @@ -55,8 +71,10 @@ export function useDashboard(token, config) { if (!state.busy) { updateState({ busy: true }); try { + const { domain, keyType, accountStorage, enableImage, enableAudio, enableVideo } = state; await setNodeConfig(token, - { ...state.config, domain: state.host, accountStorage: state.storage * 1073741824 }); + { domain, accountStorage: accountStorage * 1073741824, + keyType, enableImage, enableAudio, enableVideo }); updateState({ showSettings: false }); } catch(err) { @@ -92,13 +110,11 @@ export function useDashboard(token, config) { }; useEffect(() => { - let storage = config.accountStorage / 1073741824; - if (storage > 1) { - storage = Math.ceil(storage); - } - updateState({ host: config.domain, storage: storage }); + const { accountStorage, domain, keyType, enableImage, enableAudio, enableVideo } = config; + updateState({ domain, accountStorage: Math.ceil(accountStorage / 1073741824), keyType, + enableImage, enableAudio, enableVideo }); actions.getAccounts(); - }, []); + }, [config]); return { state, actions }; } diff --git a/net/web/src/context/useConversationContext.hook.js b/net/web/src/context/useConversationContext.hook.js index a5fe9d62..f41d551e 100644 --- a/net/web/src/context/useConversationContext.hook.js +++ b/net/web/src/context/useConversationContext.hook.js @@ -18,6 +18,9 @@ export function useConversationContext() { members: new Set(), topics: new Map(), revision: null, + enableImage: null, + enabelAudio: null, + enableVideo: null, }); const EVENT_OPEN = 1; @@ -198,12 +201,16 @@ export function useConversationContext() { let subject = getSubject(chan); let contacts = getContacts(chan); let members = getMembers(chan); + const { enableImage, enableAudio, enableVideo } = chan.data.channelDetail; updateState({ init: true, error: false, subject, contacts, members, + enableImage, + enableAudio, + enableVideo, topics: topics.current, revision: channelView.current.revision, }); diff --git a/net/web/src/session/conversation/addTopic/AddTopic.jsx b/net/web/src/session/conversation/addTopic/AddTopic.jsx index 5b250eaf..a56fe9a9 100644 --- a/net/web/src/session/conversation/addTopic/AddTopic.jsx +++ b/net/web/src/session/conversation/addTopic/AddTopic.jsx @@ -104,15 +104,21 @@ export function AddTopic({ cardId, channelId }) { value={state.messageText} autocapitalize="none" />
-
attachImage.current.click()}> - -
-
attachVideo.current.click()}> - -
-
attachAudio.current.click()}> - -
+ { state.enableImage && ( +
attachImage.current.click()}> + +
+ )} + { state.enableVideo && ( +
attachVideo.current.click()}> + +
+ )} + { state.enableAudio && ( +
attachAudio.current.click()}> + +
+ )}
diff --git a/net/web/src/session/conversation/addTopic/useAddTopic.hook.js b/net/web/src/session/conversation/addTopic/useAddTopic.hook.js index 3345fa5d..bb137298 100644 --- a/net/web/src/session/conversation/addTopic/useAddTopic.hook.js +++ b/net/web/src/session/conversation/addTopic/useAddTopic.hook.js @@ -1,10 +1,14 @@ -import { useContext, useState } from 'react'; +import { useContext, useState, useEffect } from 'react'; import { CardContext } from 'context/CardContext'; import { ChannelContext } from 'context/ChannelContext'; +import { ConversationContext } from 'context/ConversationContext'; export function useAddTopic(cardId, channelId) { const [state, setState] = useState({ + enableImage: null, + enableAudio: null, + enableVideo: null, assets: [], messageText: null, textColor: '#444444', @@ -16,6 +20,7 @@ export function useAddTopic(cardId, channelId) { const card = useContext(CardContext); const channel = useContext(ChannelContext); + const conversation = useContext(ConversationContext); const updateState = (value) => { setState((s) => ({ ...s, ...value })); @@ -43,6 +48,11 @@ export function useAddTopic(cardId, channelId) { }); } + useEffect(() => { + const { enableImage, enableAudio, enableVideo } = conversation.state; + updateState({ enableImage, enableAudio, enableVideo }); + }, [conversation]); + const actions = { addImage: (image) => { let url = URL.createObjectURL(image);