tail toggle

This commit is contained in:
Levitating Pineapple 2024-08-24 20:05:41 +03:00
parent 29cc2cfb0c
commit 6ab5e7d02f
No known key found for this signature in database
GPG key ID: 6EAADA587E14B73A
3 changed files with 68 additions and 42 deletions

View file

@ -15,31 +15,48 @@ import SimpleXChat
/// by retaining pill shape, even when ``ChatItem``'s height is less that twice its corner radius
struct ChatItemClipped: ViewModifier {
@AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var roundness = defaultChatItemRoundness
private let itemShape: ChatItemShape
@AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var isTailEnabled = true
init() { itemShape = .roundRect(maxRadius: 8) }
let chatItem: ChatItem?
let isTailVisible: Bool
init() {
chatItem = nil
isTailVisible = false
}
init(_ chatItem: ChatItem, isTailVisible: Bool) {
itemShape = switch chatItem.content {
case
.sndMsgContent,
.rcvMsgContent,
.rcvDecryptionError,
.rcvGroupInvitation,
.sndGroupInvitation,
.sndDeleted,
.rcvDeleted,
.rcvIntegrityError,
.sndModerated,
.rcvModerated,
.rcvBlocked,
.invalidJSON: .bubble(
padding: ChatBubble.paddingEdge(for: chatItem),
isTailVisible: Self.hidesTail(chatItem.content.msgContent)
? false
: isTailVisible
)
default: .roundRect(maxRadius: 8)
self.chatItem = chatItem
self.isTailVisible = isTailVisible
}
fileprivate func itemShape() -> ChatItemShape {
if let chatItem {
switch chatItem.content {
case
.sndMsgContent,
.rcvMsgContent,
.rcvDecryptionError,
.rcvGroupInvitation,
.sndGroupInvitation,
.sndDeleted,
.rcvDeleted,
.rcvIntegrityError,
.sndModerated,
.rcvModerated,
.rcvBlocked,
.invalidJSON: isTailEnabled
? .bubble(
padding: chatItem.chatDir.sent ? .trailing : .leading,
isTailVisible: Self.hidesTail(chatItem.content.msgContent)
? false
: isTailVisible
)
: .roundRect(maxRadius: ChatBubble.maxRadius)
default: .roundRect(maxRadius: 8)
}
} else {
.roundRect(maxRadius: 8)
}
}
@ -53,7 +70,7 @@ struct ChatItemClipped: ViewModifier {
}
func body(content: Content) -> some View {
let shape = ChatBubble(roundness: roundness, shapePath: itemShape)
let shape = ChatBubble(roundness: roundness, shapePath: itemShape())
content
.contentShape(.dragPreview, shape)
.contentShape(.contextMenuPreview, shape)
@ -61,6 +78,22 @@ struct ChatItemClipped: ViewModifier {
}
}
struct ChatTailPadding: ViewModifier {
@AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var tailEnabled = true
let chatItem: ChatItem
func body(content: Content) -> some View {
if tailEnabled {
content.padding(
chatItem.chatDir.sent ? .trailing : .leading,
ChatBubble.tailSize
)
} else {
content
}
}
}
struct ChatBubble: Shape {
static let tailSize: Double = 8
static let maxRadius: Double = 16
@ -118,25 +151,10 @@ struct ChatBubble: Shape {
.scale(x: -1, y: 1, anchor: .center)
.path(in: rect)
}
case .roundRect:
return Path(roundedRect: rect, cornerRadius: 8 * roundness)
case let .roundRect(radius):
return Path(roundedRect: rect, cornerRadius: radius * roundness)
}
}
static func paddingEdge(for chatItem: ChatItem) -> HorizontalEdge {
chatItem.chatDir.sent ? .trailing : .leading
}
}
struct ChatTailPadding: ViewModifier {
let chatItem: ChatItem
func body(content: Content) -> some View {
content.padding(
chatItem.chatDir.sent ? .trailing : .leading,
ChatBubble.tailSize
)
}
}
fileprivate enum ChatItemShape {

View file

@ -34,6 +34,7 @@ struct AppearanceSettings: View {
@State private var darkModeTheme: String = UserDefaults.standard.string(forKey: DEFAULT_SYSTEM_DARK_THEME) ?? DefaultTheme.DARK.themeName
@AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var profileImageCornerRadius = defaultProfileImageCorner
@AppStorage(DEFAULT_CHAT_ITEM_ROUNDNESS) private var chatItemRoundness = defaultChatItemRoundness
@AppStorage(DEFAULT_CHAT_ITEM_TAIL) private var chatItemTail = true
@AppStorage(GROUP_DEFAULT_ONE_HAND_UI, store: groupDefaults) private var oneHandUI = true
@AppStorage(DEFAULT_TOOLBAR_MATERIAL) private var toolbarMaterial = ToolbarMaterial.defaultMaterial
@ -180,8 +181,12 @@ struct AppearanceSettings: View {
}
}
Section(header: Text("Message roundness").foregroundColor(theme.colors.secondary)) {
Slider(value: $chatItemRoundness, in: 0...1, step: 0.1)
Section(header: Text("Messages").foregroundColor(theme.colors.secondary)) {
HStack {
Text("Roundness")
Slider(value: $chatItemRoundness, in: 0...1, step: 0.1)
}
Toggle("Tail", isOn: $chatItemTail)
}
Section(header: Text("Profile images").foregroundColor(theme.colors.secondary)) {

View file

@ -48,6 +48,7 @@ let DEFAULT_ACCENT_COLOR_BLUE = "accentColorBlue" // deprecated, only used for m
let DEFAULT_USER_INTERFACE_STYLE = "userInterfaceStyle" // deprecated, only used for migration
let DEFAULT_PROFILE_IMAGE_CORNER_RADIUS = "profileImageCornerRadius"
let DEFAULT_CHAT_ITEM_ROUNDNESS = "chatItemRoundness"
let DEFAULT_CHAT_ITEM_TAIL = "chatItemTail"
let DEFAULT_ONE_HAND_UI_CARD_SHOWN = "oneHandUICardShown"
let DEFAULT_TOOLBAR_MATERIAL = "toolbarMaterial"
let DEFAULT_CONNECT_VIA_LINK_TAB = "connectViaLinkTab"
@ -99,6 +100,8 @@ let appDefaults: [String: Any] = [
DEFAULT_DEVELOPER_TOOLS: false,
DEFAULT_ENCRYPTION_STARTED: false,
DEFAULT_PROFILE_IMAGE_CORNER_RADIUS: defaultProfileImageCorner,
DEFAULT_CHAT_ITEM_ROUNDNESS: defaultChatItemRoundness,
DEFAULT_CHAT_ITEM_TAIL: true,
DEFAULT_ONE_HAND_UI_CARD_SHOWN: false,
DEFAULT_TOOLBAR_MATERIAL: ToolbarMaterial.defaultMaterial,
DEFAULT_CONNECT_VIA_LINK_TAB: ConnectViaLinkTab.scan.rawValue,