mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
* wip
* refactor, fix bindings
* wip
* wip
* fixes
* wip
* information map, logos
* global conditions hack
* restructure
* restructure
* texts
* text
* restructure
* wip
* restructure
* rename
* wip
* conditions for all
* comment
* onboarding wip
* onboarding wip
* fix paddings
* fix paddings
* wip
* fix padding
* onboarding wip
* nav link instead of sheet
* pretty button
* large titles
* notifications mode button style
* reenable demo operator
* Revert "reenable demo operator"
This reverts commit 42111eb333
.
* padding
* reenable demo operator
* refactor (removes additional model api)
* style
* bold
* bold
* light/dark
* fix button
* comment
* wip
* remove preset
* new types
* api types
* apis
* smp and xftp servers in single view
* test operator servers, refactor
* save in main view
* better progress
* better in progress
* remove shadow
* update
* apis
* conditions view wip
* load text
* remove custom servers button from onboarding, open already conditions in nav link
* allow to continue with simplex on onboarding
* footer
* existing users notice
* fix to not show nothing on no action
* disable notice
* review later
* disable notice
* wip
* wip
* wip
* wip
* optional tag
* fix
* fix tags
* fix
* wip
* remove coding keys
* fix onboarding
* rename
* rework model wip
* wip
* wip
* wip
* fix
* wip
* wip
* delete
* simplify
* wip
* fix delete
* ios: server operators ui wip
* refactor
* edited
* save servers on dismiss/back
* ios: add address card and remove address from onboarding (#5181)
* ios: add address card and remove address from onboarding
* allow for address creation in info when open via card
* conditions interactions wip
* conditions interactions wip
* fix
* wip
* wip
* wip
* wip
* rename
* wip
* fix
* remove operator binding
* fix set enabled
* rename
* cleanup
* text
* fix info view dark mode
* update lib
* ios: operators & servers validation
* fix
* ios: align onboarding style
* ios: align onboarding style
* ios: operators info (#5207)
* ios: operators info
* update
* update texts
* texts
---------
Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
---------
Co-authored-by: Diogo <diogofncunha@gmail.com>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
734 lines
29 KiB
Swift
734 lines
29 KiB
Swift
//
|
||
// WhatsNewView.swift
|
||
// SimpleX (iOS)
|
||
//
|
||
// Created by Evgeny on 24/12/2022.
|
||
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
||
//
|
||
|
||
import SwiftUI
|
||
import SimpleXChat
|
||
|
||
private struct VersionDescription {
|
||
var version: String
|
||
var post: URL?
|
||
var features: [Feature]
|
||
}
|
||
|
||
private enum Feature: Identifiable {
|
||
case feature(Description)
|
||
case view(FeatureView)
|
||
|
||
var id: LocalizedStringKey {
|
||
switch self {
|
||
case let .feature(d): d.title
|
||
case let .view(v): v.title
|
||
}
|
||
}
|
||
}
|
||
|
||
private struct Description {
|
||
let icon: String?
|
||
let title: LocalizedStringKey
|
||
let description: LocalizedStringKey?
|
||
var subfeatures: [(icon: String, description: LocalizedStringKey)] = []
|
||
}
|
||
|
||
private struct FeatureView {
|
||
let icon: String?
|
||
let title: LocalizedStringKey
|
||
let view: () -> any View
|
||
}
|
||
|
||
private let versionDescriptions: [VersionDescription] = [
|
||
VersionDescription(
|
||
version: "v4.2",
|
||
post: URL(string: "https://simplex.chat/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "checkmark.shield",
|
||
title: "Security assessment",
|
||
description: "SimpleX Chat security was audited by Trail of Bits."
|
||
)),
|
||
.feature(Description(
|
||
icon: "person.2",
|
||
title: "Group links",
|
||
description: "Admins can create the links to join groups."
|
||
)),
|
||
.feature(Description(
|
||
icon: "checkmark",
|
||
title: "Auto-accept contact requests",
|
||
description: "With optional welcome message."
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v4.3",
|
||
post: URL(string: "https://simplex.chat/blog/20221206-simplex-chat-v4.3-voice-messages.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "mic",
|
||
title: "Voice messages",
|
||
description: "Max 30 seconds, received instantly."
|
||
)),
|
||
.feature(Description(
|
||
icon: "trash.slash",
|
||
title: "Irreversible message deletion",
|
||
description: "Your contacts can allow full message deletion."
|
||
)),
|
||
.feature(Description(
|
||
icon: "externaldrive.connected.to.line.below",
|
||
title: "Improved server configuration",
|
||
description: "Add servers by scanning QR codes."
|
||
)),
|
||
.feature(Description(
|
||
icon: "eye.slash",
|
||
title: "Improved privacy and security",
|
||
description: "Hide app screen in the recent apps."
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v4.4",
|
||
post: URL(string: "https://simplex.chat/blog/20230103-simplex-chat-v4.4-disappearing-messages.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "stopwatch",
|
||
title: "Disappearing messages",
|
||
description: "Sent messages will be deleted after set time."
|
||
)),
|
||
.feature(Description(
|
||
icon: "ellipsis.circle",
|
||
title: "Live messages",
|
||
description: "Recipients see updates as you type them."
|
||
)),
|
||
.feature(Description(
|
||
icon: "checkmark.shield",
|
||
title: "Verify connection security",
|
||
description: "Compare security codes with your contacts."
|
||
)),
|
||
.feature(Description(
|
||
icon: "camera",
|
||
title: "GIFs and stickers",
|
||
description: "Send them from gallery or custom keyboards."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "French interface",
|
||
description: "Thanks to the users – contribute via Weblate!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v4.5",
|
||
post: URL(string: "https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "person.crop.rectangle.stack",
|
||
title: "Multiple chat profiles",
|
||
description: "Different names, avatars and transport isolation."
|
||
)),
|
||
.feature(Description(
|
||
icon: "rectangle.and.pencil.and.ellipsis",
|
||
title: "Message draft",
|
||
description: "Preserve the last message draft, with attachments."
|
||
)),
|
||
.feature(Description(
|
||
icon: "network.badge.shield.half.filled",
|
||
title: "Transport isolation",
|
||
description: "By chat profile (default) or [by connection](https://simplex.chat/blog/20230204-simplex-chat-v4-5-user-chat-profiles.html#transport-isolation) (BETA)."
|
||
)),
|
||
.feature(Description(
|
||
icon: "lock.doc",
|
||
title: "Private filenames",
|
||
description: "To protect timezone, image/voice files use UTC."
|
||
)),
|
||
.feature(Description(
|
||
icon: "battery.25",
|
||
title: "Reduced battery usage",
|
||
description: "More improvements are coming soon!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Italian interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v4.6",
|
||
post: URL(string: "https://simplex.chat/blog/20230328-simplex-chat-v4-6-hidden-profiles.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "lock",
|
||
title: "Hidden chat profiles",
|
||
description: "Protect your chat profiles with a password!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "phone.arrow.up.right",
|
||
title: "Audio and video calls",
|
||
description: "Fully re-implemented - work in background!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "flag",
|
||
title: "Group moderation",
|
||
description: "Now admins can:\n- delete members' messages.\n- disable members (\"observer\" role)"
|
||
)),
|
||
.feature(Description(
|
||
icon: "plus.message",
|
||
title: "Group welcome message",
|
||
description: "Set the message shown to new members!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "battery.50",
|
||
title: "Further reduced battery usage",
|
||
description: "More improvements are coming soon!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Chinese and Spanish interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.0",
|
||
post: URL(string: "https://simplex.chat/blog/20230422-simplex-chat-vision-funding-v5-videos-files-passcode.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "arrow.up.doc",
|
||
title: "Videos and files up to 1gb",
|
||
description: "Fast and no wait until the sender is online!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "lock",
|
||
title: "App passcode",
|
||
description: "Set it instead of system authentication."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Polish interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
// Also
|
||
// preference to disable calls per contact
|
||
// access welcome message via a group profile
|
||
VersionDescription(
|
||
version: "v5.1",
|
||
post: URL(string: "https://simplex.chat/blog/20230523-simplex-chat-v5-1-message-reactions-self-destruct-passcode.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "face.smiling",
|
||
title: "Message reactions",
|
||
description: "Finally, we have them! 🚀"
|
||
)),
|
||
.feature(Description(
|
||
icon: "arrow.up.message",
|
||
title: "Better messages",
|
||
description: "- voice messages up to 5 minutes.\n- custom time to disappear.\n- editing history."
|
||
)),
|
||
.feature(Description(
|
||
icon: "lock",
|
||
title: "Self-destruct passcode",
|
||
description: "All data is erased when it is entered."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Japanese interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.2",
|
||
post: URL(string: "https://simplex.chat/blog/20230722-simplex-chat-v5-2-message-delivery-receipts.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "checkmark",
|
||
title: "Message delivery receipts!",
|
||
description: "The second tick we missed! ✅"
|
||
)),
|
||
.feature(Description(
|
||
icon: "star",
|
||
title: "Find chats faster",
|
||
description: "Filter unread and favorite chats."
|
||
)),
|
||
.feature(Description(
|
||
icon: "exclamationmark.arrow.triangle.2.circlepath",
|
||
title: "Keep your connections",
|
||
description: "Fix encryption after restoring backups."
|
||
)),
|
||
.feature(Description(
|
||
icon: "stopwatch",
|
||
title: "Make one message disappear",
|
||
description: "Even when disabled in the conversation."
|
||
)),
|
||
.feature(Description(
|
||
icon: "gift",
|
||
title: "A few more things",
|
||
description: "- more stable message delivery.\n- a bit better groups.\n- and more!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.3",
|
||
post: URL(string: "https://simplex.chat/blog/20230925-simplex-chat-v5-3-desktop-app-local-file-encryption-directory-service.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "desktopcomputer",
|
||
title: "New desktop app!",
|
||
description: "Create new profile in [desktop app](https://simplex.chat/downloads/). 💻"
|
||
)),
|
||
.feature(Description(
|
||
icon: "lock",
|
||
title: "Encrypt stored files & media",
|
||
description: "App encrypts new local files (except videos)."
|
||
)),
|
||
.feature(Description(
|
||
icon: "magnifyingglass",
|
||
title: "Discover and join groups",
|
||
description: "- connect to [directory service](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion) (BETA)!\n- delivery receipts (up to 20 members).\n- faster and more stable."
|
||
)),
|
||
.feature(Description(
|
||
icon: "theatermasks",
|
||
title: "Simplified incognito mode",
|
||
description: "Toggle incognito when connecting."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "\(4) new interface languages",
|
||
description: "Bulgarian, Finnish, Thai and Ukrainian - thanks to the users and [Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.4",
|
||
post: URL(string: "https://simplex.chat/blog/20231125-simplex-chat-v5-4-link-mobile-desktop-quantum-resistant-better-groups.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "desktopcomputer",
|
||
title: "Link mobile and desktop apps! 🔗",
|
||
description: "Via secure quantum resistant protocol."
|
||
)),
|
||
.feature(Description(
|
||
icon: "person.2",
|
||
title: "Better groups",
|
||
description: "Faster joining and more reliable messages."
|
||
)),
|
||
.feature(Description(
|
||
icon: "theatermasks",
|
||
title: "Incognito groups",
|
||
description: "Create a group using a random profile."
|
||
)),
|
||
.feature(Description(
|
||
icon: "hand.raised",
|
||
title: "Block group members",
|
||
description: "To hide unwanted messages."
|
||
)),
|
||
.feature(Description(
|
||
icon: "gift",
|
||
title: "A few more things",
|
||
description: "- optionally notify deleted contacts.\n- profile names with spaces.\n- and more!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.5",
|
||
post: URL(string: "https://simplex.chat/blog/20240124-simplex-chat-infrastructure-costs-v5-5-simplex-ux-private-notes-group-history.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "folder",
|
||
title: "Private notes",
|
||
description: "With encrypted files and media."
|
||
)),
|
||
.feature(Description(
|
||
icon: "link",
|
||
title: "Paste link to connect!",
|
||
description: "Search bar accepts invitation links."
|
||
)),
|
||
.feature(Description(
|
||
icon: "bubble.left.and.bubble.right",
|
||
title: "Join group conversations",
|
||
description: "Recent history and improved [directory bot](simplex:/contact#/?v=1-4&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2FeXSPwqTkKyDO3px4fLf1wx3MvPdjdLW3%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAaiv6MkMH44L2TcYrt_CsX3ZvM11WgbMEUn0hkIKTOho%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion)."
|
||
)),
|
||
.feature(Description(
|
||
icon: "battery.50",
|
||
title: "Improved message delivery",
|
||
description: "With reduced battery usage."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Turkish interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.6",
|
||
post: URL(string: "https://simplex.chat/blog/20240323-simplex-network-privacy-non-profit-v5-6-quantum-resistant-e2e-encryption-simple-migration.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "key",
|
||
title: "Quantum resistant encryption",
|
||
description: "Enable in direct chats (BETA)!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "tray.and.arrow.up",
|
||
title: "App data migration",
|
||
description: "Migrate to another device via QR code."
|
||
)),
|
||
.feature(Description(
|
||
icon: "phone",
|
||
title: "Picture-in-picture calls",
|
||
description: "Use the app while in the call."
|
||
)),
|
||
.feature(Description(
|
||
icon: "hand.raised",
|
||
title: "Safer groups",
|
||
description: "Admins can block a member for all."
|
||
)),
|
||
.feature(Description(
|
||
icon: "character",
|
||
title: "Hungarian interface",
|
||
description: "Thanks to the users – [contribute via Weblate](https://github.com/simplex-chat/simplex-chat/tree/stable#help-translating-simplex-chat)!"
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.7",
|
||
post: URL(string: "https://simplex.chat/blog/20240426-simplex-legally-binding-transparency-v5-7-better-user-experience.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "key",
|
||
title: "Quantum resistant encryption",
|
||
description: "Will be enabled in direct chats!"
|
||
)),
|
||
.feature(Description(
|
||
icon: "arrowshape.turn.up.forward",
|
||
title: "Forward and save messages",
|
||
description: "Message source remains private."
|
||
)),
|
||
.feature(Description(
|
||
icon: "music.note",
|
||
title: "In-call sounds",
|
||
description: "When connecting audio and video calls."
|
||
)),
|
||
.feature(Description(
|
||
icon: "person.crop.square",
|
||
title: "Shape profile images",
|
||
description: "Square, circle, or anything in between."
|
||
)),
|
||
.feature(Description(
|
||
icon: "antenna.radiowaves.left.and.right",
|
||
title: "Network management",
|
||
description: "More reliable network connection."
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v5.8",
|
||
post: URL(string: "https://simplex.chat/blog/20240604-simplex-chat-v5.8-private-message-routing-chat-themes.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "arrow.forward",
|
||
title: "Private message routing 🚀",
|
||
description: "Protect your IP address from the messaging relays chosen by your contacts.\nEnable in *Network & servers* settings."
|
||
)),
|
||
.feature(Description(
|
||
icon: "network.badge.shield.half.filled",
|
||
title: "Safely receive files",
|
||
description: "Confirm files from unknown servers."
|
||
)),
|
||
.feature(Description(
|
||
icon: "battery.50",
|
||
title: "Improved message delivery",
|
||
description: "With reduced battery usage."
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v6.0",
|
||
post: URL(string: "https://simplex.chat/blog/20240814-simplex-chat-vision-funding-v6-private-routing-new-user-experience.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: nil,
|
||
title: "New chat experience 🎉",
|
||
description: nil,
|
||
subfeatures: [
|
||
("link.badge.plus", "Connect to your friends faster."),
|
||
("archivebox", "Archive contacts to chat later."),
|
||
("trash", "Delete up to 20 messages at once."),
|
||
("platter.filled.bottom.and.arrow.down.iphone", "Use the app with one hand."),
|
||
("paintpalette", "Color chats with the new themes."),
|
||
]
|
||
)),
|
||
.feature(Description(
|
||
icon: nil,
|
||
title: "New media options",
|
||
description: nil,
|
||
subfeatures: [
|
||
("square.and.arrow.up", "Share from other apps."),
|
||
("play.circle", "Play from the chat list."),
|
||
("circle.filled.pattern.diagonalline.rectangle", "Blur for better privacy.")
|
||
]
|
||
)),
|
||
.feature(Description(
|
||
icon: "arrow.forward",
|
||
title: "Private message routing 🚀",
|
||
description: "It protects your IP address and connections."
|
||
)),
|
||
.feature(Description(
|
||
icon: "network",
|
||
title: "Better networking",
|
||
description: "Connection and servers status."
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v6.1",
|
||
post: URL(string: "https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"),
|
||
features: [
|
||
.feature(Description(
|
||
icon: "checkmark.shield",
|
||
title: "Better security ✅",
|
||
description: "SimpleX protocols reviewed by Trail of Bits."
|
||
)),
|
||
.feature(Description(
|
||
icon: "video",
|
||
title: "Better calls",
|
||
description: "Switch audio and video during the call."
|
||
)),
|
||
.feature(Description(
|
||
icon: "bolt",
|
||
title: "Better notifications",
|
||
description: "Improved delivery, reduced traffic usage.\nMore improvements are coming soon!"
|
||
)),
|
||
.feature(Description(
|
||
icon: nil,
|
||
title: "Better user experience",
|
||
description: nil,
|
||
subfeatures: [
|
||
("link", "Switch chat profile for 1-time invitations."),
|
||
("message", "Customizable message shape."),
|
||
("calendar", "Better message dates."),
|
||
("arrowshape.turn.up.right", "Forward up to 20 messages at once."),
|
||
("flag", "Delete or moderate up to 200 messages.")
|
||
]
|
||
)),
|
||
]
|
||
),
|
||
VersionDescription(
|
||
version: "v6.2 (beta.1)",
|
||
post: URL(string: "https://simplex.chat/blog/20241014-simplex-network-v6-1-security-review-better-calls-user-experience.html"),
|
||
features: [
|
||
.view(FeatureView(
|
||
icon: nil,
|
||
title: "Network decentralization",
|
||
view: newOperatorsView
|
||
)),
|
||
.feature(Description(
|
||
icon: "text.quote",
|
||
title: "Improved chat navigation",
|
||
description: "- Open chat on the first unread message.\n- Jump to quoted messages."
|
||
)),
|
||
]
|
||
)
|
||
]
|
||
|
||
private let lastVersion = versionDescriptions.last!.version
|
||
|
||
func setLastVersionDefault() {
|
||
UserDefaults.standard.set(lastVersion, forKey: DEFAULT_WHATS_NEW_VERSION)
|
||
}
|
||
|
||
func shouldShowWhatsNew() -> Bool {
|
||
let v = UserDefaults.standard.string(forKey: DEFAULT_WHATS_NEW_VERSION)
|
||
setLastVersionDefault()
|
||
return v != lastVersion
|
||
}
|
||
|
||
fileprivate func newOperatorsView() -> some View {
|
||
VStack(alignment: .leading) {
|
||
Image((operatorsInfo[.flux] ?? ServerOperator.dummyOperatorInfo).largeLogo)
|
||
.resizable()
|
||
.scaledToFit()
|
||
.frame(height: 48)
|
||
Text("The second preset operator in the app!")
|
||
.multilineTextAlignment(.leading)
|
||
.lineLimit(10)
|
||
HStack {
|
||
Button("Enable Flux") {
|
||
|
||
}
|
||
Text("for better metadata privacy.")
|
||
}
|
||
}
|
||
}
|
||
|
||
struct WhatsNewView: View {
|
||
@Environment(\.dismiss) var dismiss: DismissAction
|
||
@EnvironmentObject var theme: AppTheme
|
||
@State var currentVersion = versionDescriptions.count - 1
|
||
@State var currentVersionNav = versionDescriptions.count - 1
|
||
var viaSettings = false
|
||
@State var showWhatsNew: Bool
|
||
var showOperatorsNotice: Bool
|
||
|
||
var body: some View {
|
||
viewBody()
|
||
.task {
|
||
if showOperatorsNotice {
|
||
do {
|
||
let conditionsId = ChatModel.shared.conditions.currentConditions.conditionsId
|
||
try await setConditionsNotified(conditionsId: conditionsId)
|
||
} catch let error {
|
||
logger.error("WhatsNewView setConditionsNotified error: \(responseError(error))")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@ViewBuilder private func viewBody() -> some View {
|
||
if showWhatsNew {
|
||
whatsNewView()
|
||
} else if showOperatorsNotice {
|
||
ChooseServerOperators(onboarding: false)
|
||
}
|
||
}
|
||
|
||
private func whatsNewView() -> some View {
|
||
VStack {
|
||
TabView(selection: $currentVersion) {
|
||
ForEach(Array(versionDescriptions.enumerated()), id: \.0) { (i, v) in
|
||
ScrollView {
|
||
VStack(alignment: .leading, spacing: 16) {
|
||
Text("New in \(v.version)")
|
||
.font(.title)
|
||
.foregroundColor(theme.colors.secondary)
|
||
.frame(maxWidth: .infinity)
|
||
.padding(.vertical)
|
||
ForEach(v.features) { f in
|
||
switch f {
|
||
case let .feature(d): featureDescription(d).padding(.bottom, 8)
|
||
case let .view(v): AnyView(v.view()).padding(.bottom, 8)
|
||
}
|
||
}
|
||
if let post = v.post {
|
||
Link(destination: post) {
|
||
HStack {
|
||
Text("Read more")
|
||
Image(systemName: "arrow.up.right.circle")
|
||
}
|
||
}
|
||
}
|
||
if !viaSettings {
|
||
Spacer()
|
||
|
||
if showOperatorsNotice {
|
||
Button("View updated conditions") {
|
||
showWhatsNew = false
|
||
}
|
||
.font(.title3)
|
||
.frame(maxWidth: .infinity, alignment: .center)
|
||
} else {
|
||
Button("Ok") {
|
||
dismiss()
|
||
}
|
||
.font(.title3)
|
||
.frame(maxWidth: .infinity, alignment: .center)
|
||
}
|
||
|
||
Spacer()
|
||
}
|
||
}
|
||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
||
}
|
||
.tag(i)
|
||
}
|
||
}
|
||
.tabViewStyle(.page(indexDisplayMode: .never))
|
||
Spacer()
|
||
pagination()
|
||
}
|
||
.padding()
|
||
.onChange(of: currentVersion) { _ in
|
||
currentVersionNav = currentVersion
|
||
}
|
||
}
|
||
|
||
@ViewBuilder private func featureHeader(_ icon: String?, _ title: LocalizedStringKey) -> some View {
|
||
if let icon {
|
||
HStack(alignment: .center, spacing: 4) {
|
||
Image(systemName: icon)
|
||
.symbolRenderingMode(.monochrome)
|
||
.foregroundColor(theme.colors.secondary)
|
||
.frame(minWidth: 30, alignment: .center)
|
||
Text(title).font(.title3).bold()
|
||
}
|
||
} else {
|
||
Text(title).font(.title3).bold()
|
||
}
|
||
}
|
||
|
||
private func featureDescription(_ f: Description) -> some View {
|
||
VStack(alignment: .leading, spacing: 4) {
|
||
featureHeader(f.icon, f.title)
|
||
if let d = f.description {
|
||
Text(d)
|
||
.multilineTextAlignment(.leading)
|
||
.lineLimit(10)
|
||
}
|
||
if f.subfeatures.count > 0 {
|
||
ForEach(f.subfeatures, id: \.icon) { s in
|
||
HStack(alignment: .center, spacing: 4) {
|
||
Image(systemName: s.icon)
|
||
.symbolRenderingMode(.monochrome)
|
||
.foregroundColor(theme.colors.secondary)
|
||
.frame(minWidth: 30, alignment: .center)
|
||
Text(s.description)
|
||
.multilineTextAlignment(.leading)
|
||
.lineLimit(3)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private func pagination() -> some View {
|
||
HStack {
|
||
if currentVersionNav > 0 {
|
||
let prev = currentVersionNav - 1
|
||
Button {
|
||
currentVersionNav = prev
|
||
withAnimation { currentVersion = prev }
|
||
} label: {
|
||
HStack {
|
||
Image(systemName: "chevron.left")
|
||
Text(versionDescriptions[prev].version)
|
||
}
|
||
}
|
||
}
|
||
Spacer()
|
||
if currentVersionNav < versionDescriptions.count - 1 {
|
||
let next = currentVersionNav + 1
|
||
Button {
|
||
currentVersionNav = next
|
||
withAnimation { currentVersion = next }
|
||
} label: {
|
||
HStack {
|
||
Text(versionDescriptions[next].version)
|
||
Image(systemName: "chevron.right")
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
struct NewFeaturesView_Previews: PreviewProvider {
|
||
static var previews: some View {
|
||
WhatsNewView(showWhatsNew: true, showOperatorsNotice: false)
|
||
}
|
||
}
|