mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 09:41:02 +00:00
Automatically remove spaces in server names (#1600)
* Automatically remove spaces in server names If a server name includes a space (which can happen if the string is pasted / autocompleted), this space is removed, which results in the app not crashing. Fixes #1599 Signed-off-by: Paul Schuetz <pa.schuetz@web.de> * Format --------- Signed-off-by: Paul Schuetz <pa.schuetz@web.de> Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
parent
d32c5c004c
commit
0b5e764556
21 changed files with 135 additions and 99 deletions
|
@ -136,7 +136,7 @@ extension View {
|
|||
modelContainer(for: [
|
||||
Draft.self,
|
||||
LocalTimeline.self,
|
||||
TagGroup.self
|
||||
TagGroup.self,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import Env
|
|||
import KeychainSwift
|
||||
import Network
|
||||
import RevenueCat
|
||||
import Status
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
import Status
|
||||
|
||||
@main
|
||||
struct IceCubesApp: App {
|
||||
|
@ -217,7 +217,7 @@ struct IceCubesApp: App {
|
|||
case .active:
|
||||
watcher.watch(streams: [.user, .direct])
|
||||
UNUserNotificationCenter.current().setBadgeCount(0)
|
||||
userPreferences.reloadNotificationsCount(tokens: appAccountsManager.availableAccounts.compactMap{ $0.oauthToken })
|
||||
userPreferences.reloadNotificationsCount(tokens: appAccountsManager.availableAccounts.compactMap(\.oauthToken))
|
||||
Task {
|
||||
await userPreferences.refreshServerPreferences()
|
||||
}
|
||||
|
@ -287,9 +287,8 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||
|
||||
func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {}
|
||||
|
||||
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult {
|
||||
|
||||
UserPreferences.shared.reloadNotificationsCount(tokens: AppAccountsManager.shared.availableAccounts.compactMap{ $0.oauthToken })
|
||||
func application(_: UIApplication, didReceiveRemoteNotification _: [AnyHashable: Any]) async -> UIBackgroundFetchResult {
|
||||
UserPreferences.shared.reloadNotificationsCount(tokens: AppAccountsManager.shared.availableAccounts.compactMap(\.oauthToken))
|
||||
return .noData
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,10 @@ struct AddAccountView: View {
|
|||
|
||||
@FocusState private var isInstanceURLFieldFocused: Bool
|
||||
|
||||
private func cleanServerStr(_ server: String) -> String {
|
||||
server.replacingOccurrences(of: " ", with: "")
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
|
@ -54,6 +58,9 @@ struct AddAccountView: View {
|
|||
.textInputAutocapitalization(.never)
|
||||
.autocorrectionDisabled()
|
||||
.focused($isInstanceURLFieldFocused)
|
||||
.onChange(of: instanceName) { _, _ in
|
||||
instanceName = cleanServerStr(instanceName)
|
||||
}
|
||||
if let instanceFetchError {
|
||||
Text(instanceFetchError)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import Foundation
|
|||
import Models
|
||||
import Network
|
||||
import Nuke
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
import SwiftData
|
||||
|
||||
@MainActor
|
||||
struct SettingsTabs: View {
|
||||
|
|
|
@ -4,9 +4,9 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import Network
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
import SwiftData
|
||||
|
||||
@MainActor
|
||||
struct TimelineTab: View {
|
||||
|
|
|
@ -105,11 +105,10 @@ struct ConversationMessageView: View {
|
|||
Button {
|
||||
Task {
|
||||
do {
|
||||
let status: Status
|
||||
if isLiked {
|
||||
status = try await client.post(endpoint: Statuses.unfavorite(id: message.id))
|
||||
let status: Status = if isLiked {
|
||||
try await client.post(endpoint: Statuses.unfavorite(id: message.id))
|
||||
} else {
|
||||
status = try await client.post(endpoint: Statuses.favorite(id: message.id))
|
||||
try await client.post(endpoint: Statuses.favorite(id: message.id))
|
||||
}
|
||||
withAnimation {
|
||||
isLiked = status.favourited == true
|
||||
|
@ -122,11 +121,10 @@ struct ConversationMessageView: View {
|
|||
}
|
||||
Button { Task {
|
||||
do {
|
||||
let status: Status
|
||||
if isBookmarked {
|
||||
status = try await client.post(endpoint: Statuses.unbookmark(id: message.id))
|
||||
let status: Status = if isBookmarked {
|
||||
try await client.post(endpoint: Statuses.unbookmark(id: message.id))
|
||||
} else {
|
||||
status = try await client.post(endpoint: Statuses.bookmark(id: message.id))
|
||||
try await client.post(endpoint: Statuses.bookmark(id: message.id))
|
||||
}
|
||||
withAnimation {
|
||||
isBookmarked = status.bookmarked == true
|
||||
|
|
|
@ -18,8 +18,8 @@ import SwiftUI
|
|||
@AppStorage(ThemeKey.primaryBackground.rawValue) public var primaryBackgroundColor: Color = .white
|
||||
@AppStorage(ThemeKey.secondaryBackground.rawValue) public var secondaryBackgroundColor: Color = .gray
|
||||
@AppStorage(ThemeKey.label.rawValue) public var labelColor: Color = .black
|
||||
@AppStorage(ThemeKey.avatarPosition2.rawValue) var avatarPosition: AvatarPosition = AvatarPosition.top
|
||||
@AppStorage(ThemeKey.avatarShape2.rawValue) var avatarShape: AvatarShape = AvatarShape.rounded
|
||||
@AppStorage(ThemeKey.avatarPosition2.rawValue) var avatarPosition: AvatarPosition = .top
|
||||
@AppStorage(ThemeKey.avatarShape2.rawValue) var avatarShape: AvatarShape = .rounded
|
||||
@AppStorage(ThemeKey.selectedSet.rawValue) var storedSet: ColorSetName = .iceCubeDark
|
||||
@AppStorage(ThemeKey.statusActionsDisplay.rawValue) public var statusActionsDisplay: StatusActionsDisplay = .full
|
||||
@AppStorage(ThemeKey.statusDisplayStyle.rawValue) public var statusDisplayStyle: StatusDisplayStyle = .large
|
||||
|
|
|
@ -53,7 +53,7 @@ import SwiftUI
|
|||
|
||||
@AppStorage("share-button-behavior") public var shareButtonBehavior: PreferredShareButtonBehavior = .linkAndText
|
||||
|
||||
init() { }
|
||||
init() {}
|
||||
}
|
||||
|
||||
public static let sharedDefault = UserDefaults(suiteName: "group.com.thomasricouard.IceCubesApp")
|
||||
|
@ -73,168 +73,199 @@ import SwiftUI
|
|||
storage.showTranslateButton = showTranslateButton
|
||||
}
|
||||
}
|
||||
|
||||
public var pendingShownAtBottom : Bool {
|
||||
didSet {
|
||||
storage.pendingShownAtBottom = pendingShownAtBottom
|
||||
}
|
||||
}
|
||||
|
||||
public var isOpenAIEnabled: Bool {
|
||||
didSet {
|
||||
storage.isOpenAIEnabled = isOpenAIEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var recentlyUsedLanguages: [String] {
|
||||
didSet {
|
||||
storage.recentlyUsedLanguages = recentlyUsedLanguages
|
||||
}
|
||||
}
|
||||
|
||||
public var isSocialKeyboardEnabled: Bool {
|
||||
didSet {
|
||||
storage.isSocialKeyboardEnabled = isSocialKeyboardEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var useInstanceContentSettings: Bool {
|
||||
didSet {
|
||||
storage.useInstanceContentSettings = useInstanceContentSettings
|
||||
}
|
||||
}
|
||||
|
||||
public var appAutoExpandSpoilers: Bool {
|
||||
didSet {
|
||||
storage.appAutoExpandSpoilers = appAutoExpandSpoilers
|
||||
}
|
||||
}
|
||||
|
||||
public var appAutoExpandMedia: ServerPreferences.AutoExpandMedia {
|
||||
didSet {
|
||||
storage.appAutoExpandMedia = appAutoExpandMedia
|
||||
}
|
||||
}
|
||||
|
||||
public var appDefaultPostVisibility: Models.Visibility {
|
||||
didSet {
|
||||
storage.appDefaultPostVisibility = appDefaultPostVisibility
|
||||
}
|
||||
}
|
||||
|
||||
public var appDefaultReplyVisibility: Models.Visibility {
|
||||
didSet {
|
||||
storage.appDefaultReplyVisibility = appDefaultReplyVisibility
|
||||
}
|
||||
}
|
||||
|
||||
public var appDefaultPostsSensitive: Bool {
|
||||
didSet {
|
||||
storage.appDefaultPostsSensitive = appDefaultPostsSensitive
|
||||
}
|
||||
}
|
||||
|
||||
public var autoPlayVideo: Bool {
|
||||
didSet {
|
||||
storage.autoPlayVideo = autoPlayVideo
|
||||
}
|
||||
}
|
||||
|
||||
public var alwaysUseDeepl: Bool {
|
||||
didSet {
|
||||
storage.alwaysUseDeepl = alwaysUseDeepl
|
||||
}
|
||||
}
|
||||
|
||||
public var userDeeplAPIFree: Bool {
|
||||
didSet {
|
||||
storage.userDeeplAPIFree = userDeeplAPIFree
|
||||
}
|
||||
}
|
||||
|
||||
public var autoDetectPostLanguage: Bool {
|
||||
didSet {
|
||||
storage.autoDetectPostLanguage = autoDetectPostLanguage
|
||||
}
|
||||
}
|
||||
|
||||
public var suppressDupeReblogs: Bool {
|
||||
didSet {
|
||||
storage.suppressDupeReblogs = suppressDupeReblogs
|
||||
}
|
||||
}
|
||||
|
||||
public var inAppBrowserReaderView: Bool {
|
||||
didSet {
|
||||
storage.inAppBrowserReaderView = inAppBrowserReaderView
|
||||
}
|
||||
}
|
||||
|
||||
public var hapticTabSelectionEnabled: Bool {
|
||||
didSet {
|
||||
storage.hapticTabSelectionEnabled = hapticTabSelectionEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var hapticTimelineEnabled: Bool {
|
||||
didSet {
|
||||
storage.hapticTimelineEnabled = hapticTimelineEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var hapticButtonPressEnabled: Bool {
|
||||
didSet {
|
||||
storage.hapticButtonPressEnabled = hapticButtonPressEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var soundEffectEnabled: Bool {
|
||||
didSet {
|
||||
storage.soundEffectEnabled = soundEffectEnabled
|
||||
}
|
||||
}
|
||||
|
||||
public var showiPhoneTabLabel: Bool {
|
||||
didSet {
|
||||
storage.showiPhoneTabLabel = showiPhoneTabLabel
|
||||
}
|
||||
}
|
||||
|
||||
public var showAltTextForMedia: Bool {
|
||||
didSet {
|
||||
storage.showAltTextForMedia = showAltTextForMedia
|
||||
}
|
||||
}
|
||||
|
||||
public var showiPadSecondaryColumn: Bool {
|
||||
didSet {
|
||||
storage.showiPadSecondaryColumn = showiPadSecondaryColumn
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsStatusTrailingRight: StatusAction {
|
||||
didSet {
|
||||
storage.swipeActionsStatusTrailingRight = swipeActionsStatusTrailingRight
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsStatusTrailingLeft: StatusAction {
|
||||
didSet {
|
||||
storage.swipeActionsStatusTrailingLeft = swipeActionsStatusTrailingLeft
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsStatusLeadingLeft: StatusAction {
|
||||
didSet {
|
||||
storage.swipeActionsStatusLeadingLeft = swipeActionsStatusLeadingLeft
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsStatusLeadingRight: StatusAction {
|
||||
didSet {
|
||||
storage.swipeActionsStatusLeadingRight = swipeActionsStatusLeadingRight
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsUseThemeColor: Bool {
|
||||
didSet {
|
||||
storage.swipeActionsUseThemeColor = swipeActionsUseThemeColor
|
||||
}
|
||||
}
|
||||
|
||||
public var swipeActionsIconStyle: SwipeActionsIconStyle {
|
||||
didSet {
|
||||
storage.swipeActionsIconStyle = swipeActionsIconStyle
|
||||
}
|
||||
}
|
||||
|
||||
public var requestedReview: Bool {
|
||||
didSet {
|
||||
storage.requestedReview = requestedReview
|
||||
}
|
||||
}
|
||||
|
||||
public var collapseLongPosts: Bool {
|
||||
didSet {
|
||||
storage.collapseLongPosts = collapseLongPosts
|
||||
}
|
||||
}
|
||||
|
||||
public var shareButtonBehavior: PreferredShareButtonBehavior {
|
||||
didSet {
|
||||
storage.shareButtonBehavior = shareButtonBehavior
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum SwipeActionsIconStyle: String, CaseIterable {
|
||||
case iconWithText, iconOnly
|
||||
|
||||
|
@ -318,7 +349,7 @@ import SwiftUI
|
|||
}
|
||||
|
||||
public var totalNotificationsCount: Int {
|
||||
notificationsCount.compactMap{ $0.value }.reduce(0, +)
|
||||
notificationsCount.compactMap(\.value).reduce(0, +)
|
||||
}
|
||||
|
||||
public func reloadNotificationsCount(tokens: [OauthToken]) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
@Model public class Draft {
|
||||
@Attribute(.unique) public var id: UUID
|
||||
|
@ -8,8 +8,8 @@ import Foundation
|
|||
public var creationDate: Date
|
||||
|
||||
public init(content: String) {
|
||||
self.id = UUID()
|
||||
id = UUID()
|
||||
self.content = content
|
||||
self.creationDate = Date()
|
||||
creationDate = Date()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
@Model public class LocalTimeline {
|
||||
public var instance: String
|
||||
|
@ -8,6 +8,6 @@ import Foundation
|
|||
|
||||
public init(instance: String) {
|
||||
self.instance = instance
|
||||
self.creationDate = Date()
|
||||
creationDate = Date()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
@Model public class TagGroup: Equatable {
|
||||
public var title: String
|
||||
|
@ -12,7 +12,7 @@ import Foundation
|
|||
self.title = title
|
||||
self.symbolName = symbolName
|
||||
self.tags = tags
|
||||
self.creationDate = Date()
|
||||
creationDate = Date()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,4 +62,3 @@ public struct FeaturedTag: Codable, Identifiable {
|
|||
extension Tag: Sendable {}
|
||||
extension Tag.History: Sendable {}
|
||||
extension FeaturedTag: Sendable {}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import SwiftUI
|
||||
import SwiftData
|
||||
import DesignSystem
|
||||
import Models
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
struct DraftsListView: View {
|
||||
@AppStorage("draft_posts") public var legacyDraftPosts: [String] = []
|
||||
|
|
|
@ -161,7 +161,8 @@ public struct StatusEditorView: View {
|
|||
object: nil)
|
||||
}
|
||||
Button("action.cancel", role: .cancel) {}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ public struct TimelineView: View {
|
|||
|
||||
public init(timeline: Binding<TimelineFilter>,
|
||||
selectedTagGroup: Binding<TagGroup?>,
|
||||
scrollToTopSignal: Binding<Int>, canFilterTimeline: Bool) {
|
||||
scrollToTopSignal: Binding<Int>, canFilterTimeline: Bool)
|
||||
{
|
||||
_timeline = timeline
|
||||
_selectedTagGroup = selectedTagGroup
|
||||
_scrollToTopSignal = scrollToTopSignal
|
||||
|
|
Loading…
Reference in a new issue