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:
Paul Schuetz 2023-10-01 09:37:09 +02:00 committed by GitHub
parent d32c5c004c
commit 0b5e764556
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 135 additions and 99 deletions

View file

@ -136,7 +136,7 @@ extension View {
modelContainer(for: [
Draft.self,
LocalTimeline.self,
TagGroup.self
TagGroup.self,
])
}
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -6,9 +6,9 @@ import Foundation
import Models
import Network
import Nuke
import SwiftData
import SwiftUI
import Timeline
import SwiftData
@MainActor
struct SettingsTabs: View {

View file

@ -4,9 +4,9 @@ import DesignSystem
import Env
import Models
import Network
import SwiftData
import SwiftUI
import Timeline
import SwiftData
@MainActor
struct TimelineTab: View {

View file

@ -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

View file

@ -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

View file

@ -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]) {

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -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()
}
}

View file

@ -62,4 +62,3 @@ public struct FeaturedTag: Codable, Identifiable {
extension Tag: Sendable {}
extension Tag.History: Sendable {}
extension FeaturedTag: Sendable {}

View file

@ -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] = []

View file

@ -161,7 +161,8 @@ public struct StatusEditorView: View {
object: nil)
}
Button("action.cancel", role: .cancel) {}
})
}
)
}
}
}

View file

@ -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