mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-07-21 13:26:09 +00:00
wip
This commit is contained in:
@@ -16,6 +16,7 @@ struct CIFileView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
let file: CIFile?
|
||||
let edited: Bool
|
||||
let msgVerified: MsgVerified
|
||||
let senderProfile: LocalProfile?
|
||||
var smallViewSize: CGFloat?
|
||||
|
||||
@@ -24,9 +25,9 @@ struct CIFileView: View {
|
||||
fileIndicator()
|
||||
.simultaneousGesture(TapGesture().onEnded(fileAction))
|
||||
} else {
|
||||
let metaReserve = edited
|
||||
? " "
|
||||
: " "
|
||||
// the signature/"signature missing" icon in the overlaid meta needs reserved space too (matches CIMetaView)
|
||||
let signedReserve = (msgVerified.verified && (file?.loaded ?? true)) || msgVerified == .sigMissing ? " " : ""
|
||||
let metaReserve = (edited ? " " : " ") + signedReserve
|
||||
HStack(alignment: .bottom, spacing: 6) {
|
||||
fileIndicator()
|
||||
.padding(.top, 5)
|
||||
|
||||
@@ -151,9 +151,11 @@ func ciMetaText(
|
||||
space = textSpace
|
||||
}
|
||||
if meta.msgVerified.verified && signedFileVerified {
|
||||
appendSpace()
|
||||
r = r + colored(Text(Image("signature.plain")), resolved)
|
||||
space = textSpace
|
||||
} else if meta.msgVerified == .sigMissing {
|
||||
appendSpace()
|
||||
r = r + colored(Text(Image(systemName: "exclamationmark.triangle")), colorMode.resolve(.red))
|
||||
space = textSpace
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ struct FramedItemView: View {
|
||||
}
|
||||
|
||||
@ViewBuilder private func ciFileView(_ ci: ChatItem, _ text: String) -> some View {
|
||||
CIFileView(file: chatItem.file, edited: chatItem.meta.itemEdited, senderProfile: ciSenderProfile(chatItem, chat.chatInfo))
|
||||
CIFileView(file: chatItem.file, edited: chatItem.meta.itemEdited, msgVerified: chatItem.meta.msgVerified, senderProfile: ciSenderProfile(chatItem, chat.chatInfo))
|
||||
.overlay(DetermineWidth())
|
||||
if text != "" || ci.meta.isLive {
|
||||
ciMsgContentView (chatItem)
|
||||
|
||||
@@ -120,7 +120,7 @@ struct GroupPreferencesView: View {
|
||||
get: { enableFeature.wrappedValue == .on },
|
||||
set: { on, _ in enableFeature.wrappedValue = on ? .on : .off }
|
||||
)
|
||||
settingsRow(icon, color: color) {
|
||||
settingsRow(icon, color: color, customImage: feature.customImage) {
|
||||
Toggle(feature.text(isChannel: groupInfo.isChannel), isOn: enable)
|
||||
}
|
||||
.disabled(disabled)
|
||||
@@ -143,7 +143,7 @@ struct GroupPreferencesView: View {
|
||||
.frame(height: 36)
|
||||
}
|
||||
} else {
|
||||
settingsRow(icon, color: color) {
|
||||
settingsRow(icon, color: color, customImage: feature.customImage) {
|
||||
infoRow(Text(feature.text(isChannel: groupInfo.isChannel)), enableFeature.wrappedValue.text)
|
||||
}
|
||||
if timedOn {
|
||||
|
||||
@@ -438,7 +438,7 @@ struct ChatPreviewView: View {
|
||||
}
|
||||
case .file:
|
||||
smallContentPreviewFile(size: dynamicMediaSize) {
|
||||
CIFileView(file: ci.file, edited: ci.meta.itemEdited, senderProfile: ciSenderProfile(ci, chat.chatInfo), smallViewSize: dynamicMediaSize)
|
||||
CIFileView(file: ci.file, edited: ci.meta.itemEdited, msgVerified: ci.meta.msgVerified, senderProfile: ciSenderProfile(ci, chat.chatInfo), smallViewSize: dynamicMediaSize)
|
||||
}
|
||||
case let .chat(_, chatLink, ownerSig):
|
||||
smallContentPreview(size: dynamicMediaSize, borderColor: chatLink.image != nil ? .secondary : .clear) {
|
||||
|
||||
@@ -530,9 +530,11 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func settingsRow<Content : View>(_ icon: String, color: Color/* = .secondary*/, content: @escaping () -> Content) -> some View {
|
||||
func settingsRow<Content : View>(_ icon: String, color: Color/* = .secondary*/, customImage: Bool = false, content: @escaping () -> Content) -> some View {
|
||||
ZStack(alignment: .leading) {
|
||||
Image(systemName: icon).frame(maxWidth: 24, maxHeight: 24, alignment: .center)
|
||||
// custom symbol sets (e.g. "signature.plain") are asset images, SF Symbols are system images
|
||||
(customImage ? Image(icon) : Image(systemName: icon))
|
||||
.frame(maxWidth: 24, maxHeight: 24, alignment: .center)
|
||||
.symbolRenderingMode(.monochrome)
|
||||
.foregroundColor(color)
|
||||
content().padding(.leading, indent)
|
||||
|
||||
@@ -1005,7 +1005,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
||||
case .reports: return "flag"
|
||||
case .history: return "clock"
|
||||
case .support: return "questionmark.circle"
|
||||
case .signMessages: return "signature"
|
||||
case .signMessages: return "signature.plain"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,7 +1021,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
||||
case .reports: return "flag.fill"
|
||||
case .history: return "clock.fill"
|
||||
case .support: return "questionmark.circle.fill"
|
||||
case .signMessages: return "signature"
|
||||
case .signMessages: return "signature.plain"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1032,6 +1032,13 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
public var customImage: Bool {
|
||||
switch self {
|
||||
case .signMessages: return true
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
public func enableDescription(_ enabled: GroupFeatureEnabled, _ canEdit: Bool, isChannel: Bool = false) -> LocalizedStringKey {
|
||||
if canEdit {
|
||||
switch self {
|
||||
|
||||
+3
@@ -110,8 +110,10 @@ private fun CIMetaText(
|
||||
StatusIconText(painterResource(if (encrypted) MR.images.ic_lock else MR.images.ic_lock_open_right), color)
|
||||
}
|
||||
if (meta.msgVerified.verified && signedFileVerified) {
|
||||
Spacer(Modifier.width(4.dp))
|
||||
StatusIconText(painterResource(MR.images.ic_signature), color)
|
||||
} else if (meta.msgVerified is MsgVerified.SigMissing) {
|
||||
Spacer(Modifier.width(4.dp))
|
||||
StatusIconText(painterResource(MR.images.ic_warning), Color.Red)
|
||||
}
|
||||
|
||||
@@ -176,6 +178,7 @@ fun reserveSpaceForMeta(
|
||||
space = whiteSpace
|
||||
}
|
||||
if ((meta.msgVerified.verified && signedFileVerified) || meta.msgVerified is MsgVerified.SigMissing) {
|
||||
appendSpace()
|
||||
res += iconSpace
|
||||
space = whiteSpace
|
||||
}
|
||||
|
||||
+22
-1
@@ -139,6 +139,7 @@ This file is generated automatically.
|
||||
- [MsgReaction](#msgreaction)
|
||||
- [MsgReceiptStatus](#msgreceiptstatus)
|
||||
- [MsgSigStatus](#msgsigstatus)
|
||||
- [MsgVerified](#msgverified)
|
||||
- [NameErrorType](#nameerrortype)
|
||||
- [NetworkError](#networkerror)
|
||||
- [NewUser](#newuser)
|
||||
@@ -872,7 +873,7 @@ Group:
|
||||
- editable: bool
|
||||
- forwardedByMember: int64?
|
||||
- showGroupAsSender: bool
|
||||
- msgSigned: [MsgSigStatus](#msgsigstatus)?
|
||||
- msgVerified: [MsgVerified](#msgverified)
|
||||
- createdAt: UTCTime
|
||||
- updatedAt: UTCTime
|
||||
|
||||
@@ -2218,6 +2219,7 @@ Phone:
|
||||
- support: [SupportGroupPreference](#supportgrouppreference)
|
||||
- sessions: [RoleGroupPreference](#rolegrouppreference)
|
||||
- comments: [CommentsGroupPreference](#commentsgrouppreference)
|
||||
- signMessages: [GroupPreference](#grouppreference)
|
||||
- commands: [[ChatBotCommand](#chatbotcommand)]
|
||||
|
||||
|
||||
@@ -2310,6 +2312,7 @@ MemberSupport:
|
||||
- "support"
|
||||
- "sessions"
|
||||
- "comments"
|
||||
- "signMessages"
|
||||
|
||||
|
||||
---
|
||||
@@ -2551,6 +2554,7 @@ UpdateRequired:
|
||||
- support: [SupportGroupPreference](#supportgrouppreference)?
|
||||
- sessions: [RoleGroupPreference](#rolegrouppreference)?
|
||||
- comments: [CommentsGroupPreference](#commentsgrouppreference)?
|
||||
- signMessages: [GroupPreference](#grouppreference)?
|
||||
- commands: [[ChatBotCommand](#chatbotcommand)]?
|
||||
|
||||
|
||||
@@ -2951,6 +2955,23 @@ Unknown:
|
||||
- "signedNoKey"
|
||||
|
||||
|
||||
---
|
||||
|
||||
## MsgVerified
|
||||
|
||||
**Discriminated union type**:
|
||||
|
||||
Signed:
|
||||
- type: "signed"
|
||||
- sigStatus: [MsgSigStatus](#msgsigstatus)
|
||||
|
||||
SigMissing:
|
||||
- type: "sigMissing"
|
||||
|
||||
Unsigned:
|
||||
- type: "unsigned"
|
||||
|
||||
|
||||
---
|
||||
|
||||
## NameErrorType
|
||||
|
||||
@@ -322,6 +322,7 @@ chatTypesDocsData =
|
||||
(sti @MsgReaction, STUnion, "MR", [], "", ""),
|
||||
(sti @MsgReceiptStatus, STEnum, "MR", [], "", ""),
|
||||
(sti @MsgSigStatus, STEnum, "MSS", [], "", ""),
|
||||
(sti @MsgVerified, STUnion, "MV", [], "", ""),
|
||||
(sti @NameErrorType, STUnion, "", [], "", ""),
|
||||
(sti @NetworkError, STUnion, "NE", [], "", ""),
|
||||
(sti @NewUser, STRecord, "", [], "", ""),
|
||||
@@ -554,6 +555,7 @@ deriving instance Generic MsgFilter
|
||||
deriving instance Generic MsgReaction
|
||||
deriving instance Generic MsgReceiptStatus
|
||||
deriving instance Generic MsgSigStatus
|
||||
deriving instance Generic MsgVerified
|
||||
deriving instance Generic NameErrorType
|
||||
deriving instance Generic NetworkError
|
||||
deriving instance Generic NewUser
|
||||
|
||||
@@ -240,7 +240,8 @@ toTypeInfo tr =
|
||||
[ "FullDeleteGroupPreference",
|
||||
"ReactionsGroupPreference",
|
||||
"ReportsGroupPreference",
|
||||
"HistoryGroupPreference"
|
||||
"HistoryGroupPreference",
|
||||
"SignMessagesGroupPreference"
|
||||
]
|
||||
roleGroupPrefTypes =
|
||||
[ "DirectMessagesGroupPreference",
|
||||
|
||||
@@ -841,7 +841,7 @@ export interface CIMeta {
|
||||
editable: boolean
|
||||
forwardedByMember?: number // int64
|
||||
showGroupAsSender: boolean
|
||||
msgSigned?: MsgSigStatus
|
||||
msgVerified: MsgVerified
|
||||
createdAt: string // ISO-8601 timestamp
|
||||
updatedAt: string // ISO-8601 timestamp
|
||||
}
|
||||
@@ -2529,6 +2529,7 @@ export interface FullGroupPreferences {
|
||||
support: SupportGroupPreference
|
||||
sessions: RoleGroupPreference
|
||||
comments: CommentsGroupPreference
|
||||
signMessages: GroupPreference
|
||||
commands: ChatBotCommand[]
|
||||
}
|
||||
|
||||
@@ -2603,6 +2604,7 @@ export enum GroupFeature {
|
||||
Support = "support",
|
||||
Sessions = "sessions",
|
||||
Comments = "comments",
|
||||
SignMessages = "signMessages",
|
||||
}
|
||||
|
||||
export enum GroupFeatureEnabled {
|
||||
@@ -2812,6 +2814,7 @@ export interface GroupPreferences {
|
||||
support?: SupportGroupPreference
|
||||
sessions?: RoleGroupPreference
|
||||
comments?: CommentsGroupPreference
|
||||
signMessages?: GroupPreference
|
||||
commands?: ChatBotCommand[]
|
||||
}
|
||||
|
||||
@@ -3207,6 +3210,29 @@ export enum MsgSigStatus {
|
||||
SignedNoKey = "signedNoKey",
|
||||
}
|
||||
|
||||
export type MsgVerified = MsgVerified.Signed | MsgVerified.SigMissing | MsgVerified.Unsigned
|
||||
|
||||
export namespace MsgVerified {
|
||||
export type Tag = "signed" | "sigMissing" | "unsigned"
|
||||
|
||||
interface Interface {
|
||||
type: Tag
|
||||
}
|
||||
|
||||
export interface Signed extends Interface {
|
||||
type: "signed"
|
||||
sigStatus: MsgSigStatus
|
||||
}
|
||||
|
||||
export interface SigMissing extends Interface {
|
||||
type: "sigMissing"
|
||||
}
|
||||
|
||||
export interface Unsigned extends Interface {
|
||||
type: "unsigned"
|
||||
}
|
||||
}
|
||||
|
||||
export type NameErrorType = NameErrorType.NO_RESOLVER | NameErrorType.NOT_FOUND | NameErrorType.RESOLVER
|
||||
|
||||
export namespace NameErrorType {
|
||||
|
||||
@@ -587,7 +587,7 @@ class CIMeta(TypedDict):
|
||||
editable: bool
|
||||
forwardedByMember: NotRequired[int] # int64
|
||||
showGroupAsSender: bool
|
||||
msgSigned: NotRequired["MsgSigStatus"]
|
||||
msgVerified: "MsgVerified"
|
||||
createdAt: str # ISO-8601 timestamp
|
||||
updatedAt: str # ISO-8601 timestamp
|
||||
|
||||
@@ -1775,6 +1775,7 @@ class FullGroupPreferences(TypedDict):
|
||||
support: "SupportGroupPreference"
|
||||
sessions: "RoleGroupPreference"
|
||||
comments: "CommentsGroupPreference"
|
||||
signMessages: "GroupPreference"
|
||||
commands: list["ChatBotCommand"]
|
||||
|
||||
class FullPreferences(TypedDict):
|
||||
@@ -1818,7 +1819,7 @@ class GroupDirectInvitation(TypedDict):
|
||||
fromGroupMemberConnId_: NotRequired[int] # int64
|
||||
groupDirectInvStartedConnection: bool
|
||||
|
||||
GroupFeature = Literal["timedMessages", "directMessages", "fullDelete", "reactions", "voice", "files", "simplexLinks", "reports", "history", "support", "sessions", "comments"]
|
||||
GroupFeature = Literal["timedMessages", "directMessages", "fullDelete", "reactions", "voice", "files", "simplexLinks", "reports", "history", "support", "sessions", "comments", "signMessages"]
|
||||
|
||||
GroupFeatureEnabled = Literal["on", "off"]
|
||||
|
||||
@@ -1966,6 +1967,7 @@ class GroupPreferences(TypedDict):
|
||||
support: NotRequired["SupportGroupPreference"]
|
||||
sessions: NotRequired["RoleGroupPreference"]
|
||||
comments: NotRequired["CommentsGroupPreference"]
|
||||
signMessages: NotRequired["GroupPreference"]
|
||||
commands: NotRequired[list["ChatBotCommand"]]
|
||||
|
||||
class GroupProfile(TypedDict):
|
||||
@@ -2243,6 +2245,20 @@ MsgReceiptStatus = Literal["ok", "badMsgHash"]
|
||||
|
||||
MsgSigStatus = Literal["verified", "signedNoKey"]
|
||||
|
||||
class MsgVerified_signed(TypedDict):
|
||||
type: Literal["signed"]
|
||||
sigStatus: "MsgSigStatus"
|
||||
|
||||
class MsgVerified_sigMissing(TypedDict):
|
||||
type: Literal["sigMissing"]
|
||||
|
||||
class MsgVerified_unsigned(TypedDict):
|
||||
type: Literal["unsigned"]
|
||||
|
||||
MsgVerified = MsgVerified_signed | MsgVerified_sigMissing | MsgVerified_unsigned
|
||||
|
||||
MsgVerified_Tag = Literal["signed", "sigMissing", "unsigned"]
|
||||
|
||||
class NameErrorType_NO_RESOLVER(TypedDict):
|
||||
type: Literal["NO_RESOLVER"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user