mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 20:29:53 +00:00
core: make member admission forwards compatible (#5893)
* core: make member admission forwards compatible * cabal file * schema * plans * inserts * plans
This commit is contained in:
parent
348961576b
commit
1f8609a31f
16 changed files with 117 additions and 42 deletions
|
@ -104,6 +104,7 @@ library
|
||||||
Simplex.Chat.Store.Postgres.Migrations
|
Simplex.Chat.Store.Postgres.Migrations
|
||||||
Simplex.Chat.Store.Postgres.Migrations.M20241220_initial
|
Simplex.Chat.Store.Postgres.Migrations.M20241220_initial
|
||||||
Simplex.Chat.Store.Postgres.Migrations.M20250402_short_links
|
Simplex.Chat.Store.Postgres.Migrations.M20250402_short_links
|
||||||
|
Simplex.Chat.Store.Postgres.Migrations.M20250512_member_admission
|
||||||
else
|
else
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
Simplex.Chat.Archive
|
Simplex.Chat.Archive
|
||||||
|
@ -234,6 +235,7 @@ library
|
||||||
Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts
|
Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts
|
||||||
Simplex.Chat.Store.SQLite.Migrations.M20250130_indexes
|
Simplex.Chat.Store.SQLite.Migrations.M20250130_indexes
|
||||||
Simplex.Chat.Store.SQLite.Migrations.M20250402_short_links
|
Simplex.Chat.Store.SQLite.Migrations.M20250402_short_links
|
||||||
|
Simplex.Chat.Store.SQLite.Migrations.M20250512_member_admission
|
||||||
other-modules:
|
other-modules:
|
||||||
Paths_simplex_chat
|
Paths_simplex_chat
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
|
|
|
@ -4290,7 +4290,7 @@ chatCommandP =
|
||||||
{ directMessages = Just DirectMessagesGroupPreference {enable = FEOn, role = Nothing},
|
{ directMessages = Just DirectMessagesGroupPreference {enable = FEOn, role = Nothing},
|
||||||
history = Just HistoryGroupPreference {enable = FEOn}
|
history = Just HistoryGroupPreference {enable = FEOn}
|
||||||
}
|
}
|
||||||
pure GroupProfile {displayName = gName, fullName, description = Nothing, image = Nothing, groupPreferences}
|
pure GroupProfile {displayName = gName, fullName, description = Nothing, image = Nothing, groupPreferences, memberAdmission = Nothing}
|
||||||
fullNameP = A.space *> textP <|> pure ""
|
fullNameP = A.space *> textP <|> pure ""
|
||||||
textP = safeDecodeUtf8 <$> A.takeByteString
|
textP = safeDecodeUtf8 <$> A.takeByteString
|
||||||
pwdP = jsonP <|> (UserPwd . safeDecodeUtf8 <$> A.takeTill (== ' '))
|
pwdP = jsonP <|> (UserPwd . safeDecodeUtf8 <$> A.takeTill (== ' '))
|
||||||
|
|
|
@ -972,7 +972,7 @@ acceptBusinessJoinRequestAsync
|
||||||
where
|
where
|
||||||
businessGroupProfile :: Profile -> GroupPreferences -> GroupProfile
|
businessGroupProfile :: Profile -> GroupPreferences -> GroupProfile
|
||||||
businessGroupProfile Profile {displayName, fullName, image} groupPreferences =
|
businessGroupProfile Profile {displayName, fullName, image} groupPreferences =
|
||||||
GroupProfile {displayName, fullName, description = Nothing, image, groupPreferences = Just groupPreferences}
|
GroupProfile {displayName, fullName, description = Nothing, image, groupPreferences = Just groupPreferences, memberAdmission = Nothing}
|
||||||
|
|
||||||
profileToSendOnAccept :: User -> Maybe IncognitoProfile -> Bool -> Profile
|
profileToSendOnAccept :: User -> Maybe IncognitoProfile -> Bool -> Profile
|
||||||
profileToSendOnAccept user ip = userProfileToSend user (getIncognitoProfile <$> ip) Nothing
|
profileToSendOnAccept user ip = userProfileToSend user (getIncognitoProfile <$> ip) Nothing
|
||||||
|
|
|
@ -136,7 +136,7 @@ getConnectionEntity db vr user@User {userId, userContactId} agentConnId = do
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupInfo {membership}
|
-- GroupInfo {membership}
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
|
|
@ -277,7 +277,7 @@ getGroupAndMember db User {userId, userContactId} groupMemberId vr = do
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupInfo {membership}
|
-- GroupInfo {membership}
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -318,7 +318,7 @@ getGroupAndMember db User {userId, userContactId} groupMemberId vr = do
|
||||||
-- | creates completely new group with a single member - the current user
|
-- | creates completely new group with a single member - the current user
|
||||||
createNewGroup :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupProfile -> Maybe Profile -> ExceptT StoreError IO GroupInfo
|
createNewGroup :: DB.Connection -> VersionRangeChat -> TVar ChaChaDRG -> User -> GroupProfile -> Maybe Profile -> ExceptT StoreError IO GroupInfo
|
||||||
createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = ExceptT $ do
|
createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = ExceptT $ do
|
||||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||||
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
||||||
currentTs <- getCurrentTime
|
currentTs <- getCurrentTime
|
||||||
customUserProfileId <- mapM (createIncognitoProfile_ db userId currentTs) incognitoProfile
|
customUserProfileId <- mapM (createIncognitoProfile_ db userId currentTs) incognitoProfile
|
||||||
|
@ -326,8 +326,8 @@ createNewGroup db vr gVar user@User {userId} groupProfile incognitoProfile = Exc
|
||||||
groupId <- liftIO $ do
|
groupId <- liftIO $ do
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||||
profileId <- insertedRowId db
|
profileId <- insertedRowId db
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
|
@ -387,7 +387,7 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
|
||||||
DB.query db "SELECT group_id FROM groups WHERE inv_queue_info = ? AND user_id = ? LIMIT 1" (connRequest, userId)
|
DB.query db "SELECT group_id FROM groups WHERE inv_queue_info = ? AND user_id = ? LIMIT 1" (connRequest, userId)
|
||||||
createGroupInvitation_ :: ExceptT StoreError IO (GroupInfo, GroupMemberId)
|
createGroupInvitation_ :: ExceptT StoreError IO (GroupInfo, GroupMemberId)
|
||||||
createGroupInvitation_ = do
|
createGroupInvitation_ = do
|
||||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||||
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
||||||
ExceptT $
|
ExceptT $
|
||||||
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
||||||
|
@ -395,8 +395,8 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
|
||||||
groupId <- liftIO $ do
|
groupId <- liftIO $ do
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||||
profileId <- insertedRowId db
|
profileId <- insertedRowId db
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
|
@ -554,13 +554,13 @@ createGroupViaLink'
|
||||||
(,) <$> getGroupInfo db vr user groupId <*> getGroupMemberById db vr user hostMemberId
|
(,) <$> getGroupInfo db vr user groupId <*> getGroupMemberById db vr user hostMemberId
|
||||||
where
|
where
|
||||||
insertGroup_ currentTs = ExceptT $ do
|
insertGroup_ currentTs = ExceptT $ do
|
||||||
let GroupProfile {displayName, fullName, description, image, groupPreferences} = groupProfile
|
let GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission} = groupProfile
|
||||||
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
withLocalDisplayName db userId displayName $ \localDisplayName -> runExceptT $ do
|
||||||
liftIO $ do
|
liftIO $ do
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)"
|
"INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
|
||||||
(displayName, fullName, description, image, userId, groupPreferences, currentTs, currentTs)
|
(displayName, fullName, description, image, userId, groupPreferences, memberAdmission, currentTs, currentTs)
|
||||||
profileId <- insertedRowId db
|
profileId <- insertedRowId db
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
|
@ -763,7 +763,7 @@ getUserGroupDetails db vr User {userId, userContactId} _contactId_ search_ = do
|
||||||
[sql|
|
[sql|
|
||||||
SELECT
|
SELECT
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
|
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
|
||||||
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
|
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
|
||||||
|
@ -1544,7 +1544,7 @@ getViaGroupMember db vr User {userId, userContactId} Contact {contactId} = do
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupInfo {membership}
|
-- GroupInfo {membership}
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -1601,7 +1601,7 @@ getViaGroupContact db vr user@User {userId} GroupMember {groupMemberId} = do
|
||||||
maybe (pure Nothing) (fmap eitherToMaybe . runExceptT . getContact db vr user) contactId_
|
maybe (pure Nothing) (fmap eitherToMaybe . runExceptT . getContact db vr user) contactId_
|
||||||
|
|
||||||
updateGroupProfile :: DB.Connection -> User -> GroupInfo -> GroupProfile -> ExceptT StoreError IO GroupInfo
|
updateGroupProfile :: DB.Connection -> User -> GroupInfo -> GroupProfile -> ExceptT StoreError IO GroupInfo
|
||||||
updateGroupProfile db user@User {userId} g@GroupInfo {groupId, localDisplayName, groupProfile = GroupProfile {displayName}} p'@GroupProfile {displayName = newName, fullName, description, image, groupPreferences}
|
updateGroupProfile db user@User {userId} g@GroupInfo {groupId, localDisplayName, groupProfile = GroupProfile {displayName}} p'@GroupProfile {displayName = newName, fullName, description, image, groupPreferences, memberAdmission}
|
||||||
| displayName == newName = liftIO $ do
|
| displayName == newName = liftIO $ do
|
||||||
currentTs <- getCurrentTime
|
currentTs <- getCurrentTime
|
||||||
updateGroupProfile_ currentTs
|
updateGroupProfile_ currentTs
|
||||||
|
@ -1619,14 +1619,14 @@ updateGroupProfile db user@User {userId} g@GroupInfo {groupId, localDisplayName,
|
||||||
db
|
db
|
||||||
[sql|
|
[sql|
|
||||||
UPDATE group_profiles
|
UPDATE group_profiles
|
||||||
SET display_name = ?, full_name = ?, description = ?, image = ?, preferences = ?, updated_at = ?
|
SET display_name = ?, full_name = ?, description = ?, image = ?, preferences = ?, member_admission = ?, updated_at = ?
|
||||||
WHERE group_profile_id IN (
|
WHERE group_profile_id IN (
|
||||||
SELECT group_profile_id
|
SELECT group_profile_id
|
||||||
FROM groups
|
FROM groups
|
||||||
WHERE user_id = ? AND group_id = ?
|
WHERE user_id = ? AND group_id = ?
|
||||||
)
|
)
|
||||||
|]
|
|]
|
||||||
(newName, fullName, description, image, groupPreferences, currentTs, userId, groupId)
|
(newName, fullName, description, image, groupPreferences, memberAdmission, currentTs, userId, groupId)
|
||||||
updateGroup_ ldn currentTs = do
|
updateGroup_ ldn currentTs = do
|
||||||
DB.execute
|
DB.execute
|
||||||
db
|
db
|
||||||
|
@ -1664,14 +1664,14 @@ updateGroupProfileFromMember db user g@GroupInfo {groupId} Profile {displayName
|
||||||
DB.query
|
DB.query
|
||||||
db
|
db
|
||||||
[sql|
|
[sql|
|
||||||
SELECT gp.display_name, gp.full_name, gp.description, gp.image, gp.preferences
|
SELECT gp.display_name, gp.full_name, gp.description, gp.image, gp.preferences, gp.member_admission
|
||||||
FROM group_profiles gp
|
FROM group_profiles gp
|
||||||
JOIN groups g ON gp.group_profile_id = g.group_profile_id
|
JOIN groups g ON gp.group_profile_id = g.group_profile_id
|
||||||
WHERE g.group_id = ?
|
WHERE g.group_id = ?
|
||||||
|]
|
|]
|
||||||
(Only groupId)
|
(Only groupId)
|
||||||
toGroupProfile (displayName, fullName, description, image, groupPreferences) =
|
toGroupProfile (displayName, fullName, description, image, groupPreferences, memberAdmission) =
|
||||||
GroupProfile {displayName, fullName, description, image, groupPreferences}
|
GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission}
|
||||||
|
|
||||||
getGroupInfo :: DB.Connection -> VersionRangeChat -> User -> Int64 -> ExceptT StoreError IO GroupInfo
|
getGroupInfo :: DB.Connection -> VersionRangeChat -> User -> Int64 -> ExceptT StoreError IO GroupInfo
|
||||||
getGroupInfo db vr User {userId, userContactId} groupId = ExceptT $ do
|
getGroupInfo db vr User {userId, userContactId} groupId = ExceptT $ do
|
||||||
|
|
|
@ -6,12 +6,14 @@ import Data.List (sortOn)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Simplex.Chat.Store.Postgres.Migrations.M20241220_initial
|
import Simplex.Chat.Store.Postgres.Migrations.M20241220_initial
|
||||||
import Simplex.Chat.Store.Postgres.Migrations.M20250402_short_links
|
import Simplex.Chat.Store.Postgres.Migrations.M20250402_short_links
|
||||||
|
import Simplex.Chat.Store.Postgres.Migrations.M20250512_member_admission
|
||||||
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
||||||
|
|
||||||
schemaMigrations :: [(String, Text, Maybe Text)]
|
schemaMigrations :: [(String, Text, Maybe Text)]
|
||||||
schemaMigrations =
|
schemaMigrations =
|
||||||
[ ("20241220_initial", m20241220_initial, Nothing),
|
[ ("20241220_initial", m20241220_initial, Nothing),
|
||||||
("20250402_short_links", m20250402_short_links, Just down_m20250402_short_links)
|
("20250402_short_links", m20250402_short_links, Just down_m20250402_short_links),
|
||||||
|
("20250512_member_admission", m20250512_member_admission, Just down_m20250512_member_admission)
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The list of migrations in ascending order by date
|
-- | The list of migrations in ascending order by date
|
||||||
|
|
|
@ -12,6 +12,7 @@ m20250402_short_links =
|
||||||
[r|
|
[r|
|
||||||
ALTER TABLE user_contact_links ADD COLUMN short_link_contact BYTEA;
|
ALTER TABLE user_contact_links ADD COLUMN short_link_contact BYTEA;
|
||||||
ALTER TABLE connections ADD COLUMN short_link_inv BYTEA;
|
ALTER TABLE connections ADD COLUMN short_link_inv BYTEA;
|
||||||
|
ALTER TABLE connections ADD COLUMN via_short_link_contact BYTEA;
|
||||||
|]
|
|]
|
||||||
|
|
||||||
down_m20250402_short_links :: Text
|
down_m20250402_short_links :: Text
|
||||||
|
@ -20,4 +21,5 @@ down_m20250402_short_links =
|
||||||
[r|
|
[r|
|
||||||
ALTER TABLE user_contact_links DROP COLUMN short_link_contact;
|
ALTER TABLE user_contact_links DROP COLUMN short_link_contact;
|
||||||
ALTER TABLE connections DROP COLUMN short_link_inv;
|
ALTER TABLE connections DROP COLUMN short_link_inv;
|
||||||
|
ALTER TABLE connections DROP COLUMN via_short_link_contact;
|
||||||
|]
|
|]
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
|
module Simplex.Chat.Store.Postgres.Migrations.M20250512_member_admission where
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import Text.RawString.QQ (r)
|
||||||
|
|
||||||
|
m20250512_member_admission :: Text
|
||||||
|
m20250512_member_admission =
|
||||||
|
T.pack
|
||||||
|
[r|
|
||||||
|
ALTER TABLE group_profiles ADD COLUMN member_admission TEXT;
|
||||||
|
|]
|
||||||
|
|
||||||
|
down_m20250512_member_admission :: Text
|
||||||
|
down_m20250512_member_admission =
|
||||||
|
T.pack
|
||||||
|
[r|
|
||||||
|
ALTER TABLE group_profiles DROP COLUMN member_admission;
|
||||||
|
|]
|
|
@ -129,6 +129,7 @@ import Simplex.Chat.Store.SQLite.Migrations.M20250126_mentions
|
||||||
import Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts
|
import Simplex.Chat.Store.SQLite.Migrations.M20250129_delete_unused_contacts
|
||||||
import Simplex.Chat.Store.SQLite.Migrations.M20250130_indexes
|
import Simplex.Chat.Store.SQLite.Migrations.M20250130_indexes
|
||||||
import Simplex.Chat.Store.SQLite.Migrations.M20250402_short_links
|
import Simplex.Chat.Store.SQLite.Migrations.M20250402_short_links
|
||||||
|
import Simplex.Chat.Store.SQLite.Migrations.M20250512_member_admission
|
||||||
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
import Simplex.Messaging.Agent.Store.Shared (Migration (..))
|
||||||
|
|
||||||
schemaMigrations :: [(String, Query, Maybe Query)]
|
schemaMigrations :: [(String, Query, Maybe Query)]
|
||||||
|
@ -257,7 +258,8 @@ schemaMigrations =
|
||||||
("20250126_mentions", m20250126_mentions, Just down_m20250126_mentions),
|
("20250126_mentions", m20250126_mentions, Just down_m20250126_mentions),
|
||||||
("20250129_delete_unused_contacts", m20250129_delete_unused_contacts, Just down_m20250129_delete_unused_contacts),
|
("20250129_delete_unused_contacts", m20250129_delete_unused_contacts, Just down_m20250129_delete_unused_contacts),
|
||||||
("20250130_indexes", m20250130_indexes, Just down_m20250130_indexes),
|
("20250130_indexes", m20250130_indexes, Just down_m20250130_indexes),
|
||||||
("20250402_short_links", m20250402_short_links, Just down_m20250402_short_links)
|
("20250402_short_links", m20250402_short_links, Just down_m20250402_short_links),
|
||||||
|
("20250512_member_admission", m20250512_member_admission, Just down_m20250512_member_admission)
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | The list of migrations in ascending order by date
|
-- | The list of migrations in ascending order by date
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
|
module Simplex.Chat.Store.SQLite.Migrations.M20250512_member_admission where
|
||||||
|
|
||||||
|
import Database.SQLite.Simple (Query)
|
||||||
|
import Database.SQLite.Simple.QQ (sql)
|
||||||
|
|
||||||
|
m20250512_member_admission :: Query
|
||||||
|
m20250512_member_admission =
|
||||||
|
[sql|
|
||||||
|
ALTER TABLE group_profiles ADD COLUMN member_admission TEXT;
|
||||||
|
|]
|
||||||
|
|
||||||
|
down_m20250512_member_admission :: Query
|
||||||
|
down_m20250512_member_admission =
|
||||||
|
[sql|
|
||||||
|
ALTER TABLE group_profiles DROP COLUMN member_admission;
|
||||||
|
|]
|
|
@ -35,7 +35,7 @@ Query:
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupInfo {membership}
|
-- GroupInfo {membership}
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -544,7 +544,7 @@ SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
|
||||||
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
|
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
|
||||||
|
|
||||||
Query:
|
Query:
|
||||||
SELECT gp.display_name, gp.full_name, gp.description, gp.image, gp.preferences
|
SELECT gp.display_name, gp.full_name, gp.description, gp.image, gp.preferences, gp.member_admission
|
||||||
FROM group_profiles gp
|
FROM group_profiles gp
|
||||||
JOIN groups g ON gp.group_profile_id = g.group_profile_id
|
JOIN groups g ON gp.group_profile_id = g.group_profile_id
|
||||||
WHERE g.group_id = ?
|
WHERE g.group_id = ?
|
||||||
|
@ -805,7 +805,7 @@ Query:
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupInfo {membership}
|
-- GroupInfo {membership}
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -850,7 +850,7 @@ SEARCH cc USING COVERING INDEX idx_connections_group_member (user_id=? AND group
|
||||||
Query:
|
Query:
|
||||||
SELECT
|
SELECT
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
|
mu.group_member_id, g.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category, mu.member_status, mu.show_messages, mu.member_restriction,
|
||||||
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
|
mu.invited_by, mu.invited_by_group_member_id, mu.local_display_name, mu.contact_id, mu.contact_profile_id, pu.contact_profile_id, pu.display_name, pu.full_name, pu.image, pu.contact_link, pu.local_alias, pu.preferences,
|
||||||
|
@ -1235,7 +1235,7 @@ SEARCH group_members USING INTEGER PRIMARY KEY (rowid=?)
|
||||||
|
|
||||||
Query:
|
Query:
|
||||||
UPDATE group_profiles
|
UPDATE group_profiles
|
||||||
SET display_name = ?, full_name = ?, description = ?, image = ?, preferences = ?, updated_at = ?
|
SET display_name = ?, full_name = ?, description = ?, image = ?, preferences = ?, member_admission = ?, updated_at = ?
|
||||||
WHERE group_profile_id IN (
|
WHERE group_profile_id IN (
|
||||||
SELECT group_profile_id
|
SELECT group_profile_id
|
||||||
FROM groups
|
FROM groups
|
||||||
|
@ -4458,7 +4458,7 @@ Query:
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupMember - membership
|
-- GroupMember - membership
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -4480,7 +4480,7 @@ Query:
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupMember - membership
|
-- GroupMember - membership
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
@ -5387,7 +5387,7 @@ Plan:
|
||||||
Query: INSERT INTO files (user_id, group_id, file_name, file_size, chunk_size, file_inline, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?)
|
Query: INSERT INTO files (user_id, group_id, file_name, file_size, chunk_size, file_inline, ci_file_status, protocol, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?)
|
||||||
Plan:
|
Plan:
|
||||||
|
|
||||||
Query: INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?)
|
Query: INSERT INTO group_profiles (display_name, full_name, description, image, user_id, preferences, member_admission, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?)
|
||||||
Plan:
|
Plan:
|
||||||
|
|
||||||
Query: INSERT INTO group_profiles (display_name, full_name, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?)
|
Query: INSERT INTO group_profiles (display_name, full_name, image, user_id, preferences, created_at, updated_at) VALUES (?,?,?,?,?,?,?)
|
||||||
|
|
|
@ -108,7 +108,8 @@ CREATE TABLE group_profiles(
|
||||||
image TEXT,
|
image TEXT,
|
||||||
user_id INTEGER DEFAULT NULL REFERENCES users ON DELETE CASCADE,
|
user_id INTEGER DEFAULT NULL REFERENCES users ON DELETE CASCADE,
|
||||||
preferences TEXT,
|
preferences TEXT,
|
||||||
description TEXT NULL
|
description TEXT NULL,
|
||||||
|
member_admission TEXT
|
||||||
);
|
);
|
||||||
CREATE TABLE groups(
|
CREATE TABLE groups(
|
||||||
group_id INTEGER PRIMARY KEY, -- local group ID
|
group_id INTEGER PRIMARY KEY, -- local group ID
|
||||||
|
|
|
@ -579,16 +579,16 @@ safeDeleteLDN db User {userId} localDisplayName = do
|
||||||
|
|
||||||
type BusinessChatInfoRow = (Maybe BusinessChatType, Maybe MemberId, Maybe MemberId)
|
type BusinessChatInfoRow = (Maybe BusinessChatType, Maybe MemberId, Maybe MemberId)
|
||||||
|
|
||||||
type GroupInfoRow = (Int64, GroupName, GroupName, Text, Text, Maybe Text, Maybe ImageData, Maybe MsgFilter, Maybe BoolInt, BoolInt, Maybe GroupPreferences) :. (UTCTime, UTCTime, Maybe UTCTime, Maybe UTCTime) :. BusinessChatInfoRow :. (Maybe UIThemeEntityOverrides, Maybe CustomData, Maybe Int64) :. GroupMemberRow
|
type GroupInfoRow = (Int64, GroupName, GroupName, Text, Text, Maybe Text, Maybe ImageData, Maybe MsgFilter, Maybe BoolInt, BoolInt, Maybe GroupPreferences, Maybe GroupMemberAdmission) :. (UTCTime, UTCTime, Maybe UTCTime, Maybe UTCTime) :. BusinessChatInfoRow :. (Maybe UIThemeEntityOverrides, Maybe CustomData, Maybe Int64) :. GroupMemberRow
|
||||||
|
|
||||||
type GroupMemberRow = (Int64, Int64, MemberId, VersionChat, VersionChat, GroupMemberRole, GroupMemberCategory, GroupMemberStatus, BoolInt, Maybe MemberRestrictionStatus) :. (Maybe Int64, Maybe GroupMemberId, ContactName, Maybe ContactId, ProfileId, ProfileId, ContactName, Text, Maybe ImageData, Maybe ConnLinkContact, LocalAlias, Maybe Preferences) :. (UTCTime, UTCTime)
|
type GroupMemberRow = (Int64, Int64, MemberId, VersionChat, VersionChat, GroupMemberRole, GroupMemberCategory, GroupMemberStatus, BoolInt, Maybe MemberRestrictionStatus) :. (Maybe Int64, Maybe GroupMemberId, ContactName, Maybe ContactId, ProfileId, ProfileId, ContactName, Text, Maybe ImageData, Maybe ConnLinkContact, LocalAlias, Maybe Preferences) :. (UTCTime, UTCTime)
|
||||||
|
|
||||||
toGroupInfo :: VersionRangeChat -> Int64 -> [ChatTagId] -> GroupInfoRow -> GroupInfo
|
toGroupInfo :: VersionRangeChat -> Int64 -> [ChatTagId] -> GroupInfoRow -> GroupInfo
|
||||||
toGroupInfo vr userContactId chatTags ((groupId, localDisplayName, displayName, fullName, localAlias, description, image, enableNtfs_, sendRcpts, BI favorite, groupPreferences) :. (createdAt, updatedAt, chatTs, userMemberProfileSentAt) :. businessRow :. (uiThemes, customData, chatItemTTL) :. userMemberRow) =
|
toGroupInfo vr userContactId chatTags ((groupId, localDisplayName, displayName, fullName, localAlias, description, image, enableNtfs_, sendRcpts, BI favorite, groupPreferences, memberAdmission) :. (createdAt, updatedAt, chatTs, userMemberProfileSentAt) :. businessRow :. (uiThemes, customData, chatItemTTL) :. userMemberRow) =
|
||||||
let membership = (toGroupMember userContactId userMemberRow) {memberChatVRange = vr}
|
let membership = (toGroupMember userContactId userMemberRow) {memberChatVRange = vr}
|
||||||
chatSettings = ChatSettings {enableNtfs = fromMaybe MFAll enableNtfs_, sendRcpts = unBI <$> sendRcpts, favorite}
|
chatSettings = ChatSettings {enableNtfs = fromMaybe MFAll enableNtfs_, sendRcpts = unBI <$> sendRcpts, favorite}
|
||||||
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
fullGroupPreferences = mergeGroupPreferences groupPreferences
|
||||||
groupProfile = GroupProfile {displayName, fullName, description, image, groupPreferences}
|
groupProfile = GroupProfile {displayName, fullName, description, image, groupPreferences, memberAdmission}
|
||||||
businessChat = toBusinessChatInfo businessRow
|
businessChat = toBusinessChatInfo businessRow
|
||||||
in GroupInfo {groupId, localDisplayName, groupProfile, localAlias, businessChat, fullGroupPreferences, membership, chatSettings, createdAt, updatedAt, chatTs, userMemberProfileSentAt, chatTags, chatItemTTL, uiThemes, customData}
|
in GroupInfo {groupId, localDisplayName, groupProfile, localAlias, businessChat, fullGroupPreferences, membership, chatSettings, createdAt, updatedAt, chatTs, userMemberProfileSentAt, chatTags, chatItemTTL, uiThemes, customData}
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ groupInfoQuery =
|
||||||
SELECT
|
SELECT
|
||||||
-- GroupInfo
|
-- GroupInfo
|
||||||
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
g.group_id, g.local_display_name, gp.display_name, gp.full_name, g.local_alias, gp.description, gp.image,
|
||||||
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences,
|
g.enable_ntfs, g.send_rcpts, g.favorite, gp.preferences, gp.member_admission,
|
||||||
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
g.created_at, g.updated_at, g.chat_ts, g.user_member_profile_sent_at, g.business_chat, g.business_member_id, g.customer_member_id, g.ui_themes, g.custom_data, g.chat_item_ttl,
|
||||||
-- GroupMember - membership
|
-- GroupMember - membership
|
||||||
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
mu.group_member_id, mu.group_id, mu.member_id, mu.peer_chat_min_version, mu.peer_chat_max_version, mu.member_role, mu.member_category,
|
||||||
|
|
|
@ -57,7 +57,7 @@ import Simplex.Messaging.Crypto.File (CryptoFileArgs (..))
|
||||||
import Simplex.Messaging.Crypto.Ratchet (PQEncryption (..), PQSupport, pattern PQEncOff)
|
import Simplex.Messaging.Crypto.Ratchet (PQEncryption (..), PQSupport, pattern PQEncOff)
|
||||||
import Simplex.Messaging.Encoding.String
|
import Simplex.Messaging.Encoding.String
|
||||||
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, sumTypeJSON)
|
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, sumTypeJSON)
|
||||||
import Simplex.Messaging.Util (safeDecodeUtf8, (<$?>))
|
import Simplex.Messaging.Util (decodeJSON, encodeJSON, safeDecodeUtf8, (<$?>))
|
||||||
import Simplex.Messaging.Version
|
import Simplex.Messaging.Version
|
||||||
import Simplex.Messaging.Version.Internal
|
import Simplex.Messaging.Version.Internal
|
||||||
#if defined(dbPostgres)
|
#if defined(dbPostgres)
|
||||||
|
@ -616,10 +616,24 @@ data GroupProfile = GroupProfile
|
||||||
fullName :: Text,
|
fullName :: Text,
|
||||||
description :: Maybe Text,
|
description :: Maybe Text,
|
||||||
image :: Maybe ImageData,
|
image :: Maybe ImageData,
|
||||||
groupPreferences :: Maybe GroupPreferences
|
groupPreferences :: Maybe GroupPreferences,
|
||||||
|
memberAdmission :: Maybe GroupMemberAdmission
|
||||||
}
|
}
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
data GroupMemberAdmission = GroupMemberAdmission
|
||||||
|
{ -- names :: Maybe MemberCriteria,
|
||||||
|
-- captcha :: Maybe MemberCriteria,
|
||||||
|
review :: Maybe MemberCriteria
|
||||||
|
}
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
data MemberCriteria = MCAll
|
||||||
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
emptyGroupMemberAdmission :: GroupMemberAdmission
|
||||||
|
emptyGroupMemberAdmission = GroupMemberAdmission Nothing
|
||||||
|
|
||||||
newtype ImageData = ImageData Text
|
newtype ImageData = ImageData Text
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
|
@ -1816,6 +1830,16 @@ $(JQ.deriveJSON defaultJSON ''LocalProfile)
|
||||||
|
|
||||||
$(JQ.deriveJSON defaultJSON ''UserContactRequest)
|
$(JQ.deriveJSON defaultJSON ''UserContactRequest)
|
||||||
|
|
||||||
|
$(JQ.deriveJSON (enumJSON $ dropPrefix "MC") {J.tagSingleConstructors = True} ''MemberCriteria)
|
||||||
|
|
||||||
|
$(JQ.deriveJSON defaultJSON ''GroupMemberAdmission)
|
||||||
|
|
||||||
|
instance ToField GroupMemberAdmission where
|
||||||
|
toField = toField . encodeJSON
|
||||||
|
|
||||||
|
instance FromField GroupMemberAdmission where
|
||||||
|
fromField = fromTextField_ decodeJSON
|
||||||
|
|
||||||
$(JQ.deriveJSON defaultJSON ''GroupProfile)
|
$(JQ.deriveJSON defaultJSON ''GroupProfile)
|
||||||
|
|
||||||
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "IB") ''InvitedBy)
|
$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "IB") ''InvitedBy)
|
||||||
|
|
|
@ -1680,10 +1680,10 @@ countactUserPrefText cup = case cup of
|
||||||
|
|
||||||
viewGroupUpdated :: GroupInfo -> GroupInfo -> Maybe GroupMember -> [StyledString]
|
viewGroupUpdated :: GroupInfo -> GroupInfo -> Maybe GroupMember -> [StyledString]
|
||||||
viewGroupUpdated
|
viewGroupUpdated
|
||||||
GroupInfo {localDisplayName = n, groupProfile = GroupProfile {fullName, description, image, groupPreferences = gps}}
|
GroupInfo {localDisplayName = n, groupProfile = GroupProfile {fullName, description, image, groupPreferences = gps, memberAdmission = ma}}
|
||||||
g'@GroupInfo {localDisplayName = n', groupProfile = GroupProfile {fullName = fullName', description = description', image = image', groupPreferences = gps'}}
|
g'@GroupInfo {localDisplayName = n', groupProfile = GroupProfile {fullName = fullName', description = description', image = image', groupPreferences = gps', memberAdmission = ma'}}
|
||||||
m = do
|
m = do
|
||||||
let update = groupProfileUpdated <> groupPrefsUpdated
|
let update = groupProfileUpdated <> groupPrefsUpdated <> memberAdmissionUpdated
|
||||||
if null update
|
if null update
|
||||||
then []
|
then []
|
||||||
else memberUpdated <> update
|
else memberUpdated <> update
|
||||||
|
@ -1704,6 +1704,9 @@ viewGroupUpdated
|
||||||
| otherwise = Just . plain $ groupPreferenceText (pref gps')
|
| otherwise = Just . plain $ groupPreferenceText (pref gps')
|
||||||
where
|
where
|
||||||
pref = getGroupPreference f . mergeGroupPreferences
|
pref = getGroupPreference f . mergeGroupPreferences
|
||||||
|
memberAdmissionUpdated
|
||||||
|
| ma == ma' = []
|
||||||
|
| otherwise = ["changed member admission rules"]
|
||||||
|
|
||||||
viewGroupProfile :: GroupInfo -> [StyledString]
|
viewGroupProfile :: GroupInfo -> [StyledString]
|
||||||
viewGroupProfile g@GroupInfo {groupProfile = GroupProfile {description, image, groupPreferences = gps}} =
|
viewGroupProfile g@GroupInfo {groupProfile = GroupProfile {description, image, groupPreferences = gps}} =
|
||||||
|
|
|
@ -107,7 +107,7 @@ testProfile :: Profile
|
||||||
testProfile = Profile {displayName = "alice", fullName = "Alice", image = Just (ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="), contactLink = Nothing, preferences = testChatPreferences}
|
testProfile = Profile {displayName = "alice", fullName = "Alice", image = Just (ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="), contactLink = Nothing, preferences = testChatPreferences}
|
||||||
|
|
||||||
testGroupProfile :: GroupProfile
|
testGroupProfile :: GroupProfile
|
||||||
testGroupProfile = GroupProfile {displayName = "team", fullName = "Team", description = Nothing, image = Nothing, groupPreferences = testGroupPreferences}
|
testGroupProfile = GroupProfile {displayName = "team", fullName = "Team", description = Nothing, image = Nothing, groupPreferences = testGroupPreferences, memberAdmission = Nothing}
|
||||||
|
|
||||||
decodeChatMessageTest :: Spec
|
decodeChatMessageTest :: Spec
|
||||||
decodeChatMessageTest = describe "Chat message encoding/decoding" $ do
|
decodeChatMessageTest = describe "Chat message encoding/decoding" $ do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue