Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 61 additions & 32 deletions Modules/Sources/FavoritesFeature/FavoritesFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ public struct FavoritesFeature: Reducer, Sendable {

public init() {}

// MARK: - Localizations

public enum Localization {
static let linkCopied = LocalizedStringResource("Link copied", bundle: .module)
static let markAsReadSuccess = LocalizedStringResource("Marked as read", bundle: .module)
static let notifyTypeChanged = LocalizedStringResource("Notify type changed", bundle: .module)
static let sortFiltersChanged = LocalizedStringResource("Sort filters are changed", bundle: .module)
}

// MARK: - State

@ObservableState
Expand Down Expand Up @@ -112,10 +121,14 @@ public struct FavoritesFeature: Reducer, Sendable {
return .send(.internal(.loadFavorites(offset: newOffset)))

case .sort(.presented(.saveButtonTapped)):
return .run { send in
await send(.internal(.refresh))
await send(.sort(.presented(.cancelButtonTapped)))
}
return .concatenate(
.run { _ in
await toastClient.showToast(ToastMessage(text: Localization.sortFiltersChanged, haptic: .success))
},

.send(.internal(.refresh)),
.send(.sort(.presented(.cancelButtonTapped)))
)

case .sort(.presented(.cancelButtonTapped)):
state.sort = nil
Expand Down Expand Up @@ -178,44 +191,57 @@ public struct FavoritesFeature: Reducer, Sendable {
return .none

case .markAllAsRead:
return .run { send in
_ = try await apiClient.readAllFavorites()
// TODO: Display toast on success/error.
return .concatenate(
.run { send in
let status = try await apiClient.readAllFavorites()
let success = ToastMessage(text: Localization.markAsReadSuccess, haptic: .success)
await toastClient.showToast(status ? success : .whoopsSomethingWentWrong)
},

await send(.internal(.refresh))
}
.send(.internal(.refresh))
)
}

case .view(.commonContextMenu(let action, let isForum)):
switch action {
case .copyLink(let id):
let show = isForum ? "showforum" : "showtopic"
pasteboardClient.copy("https://4pda.to/forum/index.php?\(show)=\(id)")
return .none
return .run { _ in
await toastClient.showToast(ToastMessage(text: Localization.linkCopied, haptic: .success))
}

case .delete(let id):
return .run { send in
let request = SetFavoriteRequest(id: id, action: .delete, type: isForum ? .forum : .topic)
_ = try await apiClient.setFavorite(request)
// TODO: Display toast on success/error.
return .concatenate(
.run { send in
let request = SetFavoriteRequest(id: id, action: .delete, type: isForum ? .forum : .topic)
let status = try await apiClient.setFavorite(request)
await toastClient.showToast(status ? .actionCompleted : .whoopsSomethingWentWrong)
},

await send(.internal(.refresh))
}
.send(.internal(.refresh))
)

case .setImportant(let id, let pin):
return .run { send in
let request = SetFavoriteRequest(id: id, action: pin ? .pin : .unpin, type: isForum ? .forum : .topic)
_ = try await apiClient.setFavorite(request)
// TODO: Display toast on success/error.
return .concatenate(
.run { send in
let request = SetFavoriteRequest(id: id, action: pin ? .pin : .unpin, type: isForum ? .forum : .topic)
let status = try await apiClient.setFavorite(request)
await toastClient.showToast(status ? .actionCompleted : .whoopsSomethingWentWrong)
},

await send(.internal(.refresh))
}
.send(.internal(.refresh))
)

case .markRead(let id):
return .run { [id, isForum] send in
let _ = try await apiClient.markRead(id: id, isTopic: !isForum)
await send(.internal(.refresh))
}
return .concatenate(
.run { [id, isForum] send in
let status = try await apiClient.markRead(id: id, isTopic: !isForum)
await toastClient.showToast(status ? .actionCompleted : .whoopsSomethingWentWrong)
},

.send(.internal(.refresh))
)
}

case let .view(.topicContextMenu(action, favorite)):
Expand All @@ -229,13 +255,16 @@ public struct FavoritesFeature: Reducer, Sendable {
}

case .notify(let flag, let notify):
return .run { send in
let request = NotifyFavoriteRequest(id: favorite.topic.id, flag: flag, type: notify)
_ = try await apiClient.notifyFavorite(request)
// TODO: Display toast on success/error.
return .concatenate(
.run { send in
let request = NotifyFavoriteRequest(id: favorite.topic.id, flag: flag, type: notify)
let status = try await apiClient.notifyFavorite(request)
let notifyTypeChangedToast = ToastMessage(text: Localization.notifyTypeChanged, haptic: .success)
await toastClient.showToast(status ? notifyTypeChangedToast : .whoopsSomethingWentWrong)
},

await send(.internal(.refresh))
}
.send(.internal(.refresh))
)
}

case .internal(.refresh):
Expand Down
40 changes: 40 additions & 0 deletions Modules/Sources/FavoritesFeature/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@
}
}
},
"Link copied" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ссылка скопирована"
}
}
}
},
"Mark As Read" : {
"localizations" : {
"ru" : {
Expand All @@ -141,6 +151,16 @@
}
}
},
"Marked as read" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отмечено прочитанным"
}
}
}
},
"No favorites" : {
"localizations" : {
"ru" : {
Expand Down Expand Up @@ -171,6 +191,16 @@
}
}
},
"Notify type changed" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Тип уведомлений изменен"
}
}
}
},
"Once" : {
"localizations" : {
"ru" : {
Expand Down Expand Up @@ -211,6 +241,16 @@
}
}
},
"Sort filters are changed" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Фильтры сортировки обновлены"
}
}
}
},
"To Important" : {
"localizations" : {
"ru" : {
Expand Down
36 changes: 21 additions & 15 deletions Modules/Sources/ForumFeature/ForumFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public struct ForumFeature: Reducer, Sendable {

public init() {}

// MARK: - Localizations

public enum Localization {
static let linkCopied = LocalizedStringResource("Link copied", bundle: .module)
static let markAsReadSuccess = LocalizedStringResource("Marked as read", bundle: .module)
}

// MARK: - Enums

public struct SectionExpand: Equatable {
Expand Down Expand Up @@ -197,18 +204,25 @@ public struct ForumFeature: Reducer, Sendable {
case .copyLink:
let show = isForum ? "showforum" : "showtopic"
pasteboardClient.copy("https://4pda.to/forum/index.php?\(show)=\(id)")
return .none
return .run { _ in
await toastClient.showToast(ToastMessage(text: Localization.linkCopied, haptic: .success))
}

case .openInBrowser:
let show = isForum ? "showforum" : "showtopic"
let url = URL(string: "https://4pda.to/forum/index.php?\(show)=\(id)")!
return .run { _ in await open(url: url) }

case .markRead:
return .run { [id, isForum] send in
let _ = try await apiClient.markRead(id: id, isTopic: !isForum)
await send(.internal(.refresh))
}
return .concatenate(
.run { [id, isForum] send in
let status = try await apiClient.markRead(id: id, isTopic: !isForum)
let markedAsRead = ToastMessage(text: Localization.markAsReadSuccess, haptic: .success)
await toastClient.showToast(status ? markedAsRead : .whoopsSomethingWentWrong)
},

.send(.internal(.refresh))
)

case .setFavorite(let isFavorite):
return .run { [id = id, isFavorite = isFavorite, isForum = isForum] send in
Expand All @@ -217,18 +231,10 @@ public struct ForumFeature: Reducer, Sendable {
action: isFavorite ? .delete : .add,
type: isForum ? .forum : .topic
)
let _ = try await apiClient.setFavorite(request)
let status = try await apiClient.setFavorite(request)
notificationCenter.post(name: .favoritesUpdated, object: nil)
await send(.internal(.refresh))
// TODO: We don't know if it's added or removed from api
// let text: LocalizedStringResource
// if isAdded {
// text = LocalizedStringResource("Added to favorites", bundle: .module)
// } else {
// text = LocalizedStringResource("Removed from favorites", bundle: .module)
// }
// let toast = ToastMessage(text: text, haptic: .success)
// await toastClient.showToast(toast)
await toastClient.showToast(status ? .actionCompleted : .whoopsSomethingWentWrong)
} catch: { _, _ in
await toastClient.showToast(.whoopsSomethingWentWrong)
}
Expand Down
20 changes: 20 additions & 0 deletions Modules/Sources/ForumFeature/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@
}
}
},
"Link copied" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ссылка скопирована"
}
}
}
},
"Mark Read" : {
"localizations" : {
"ru" : {
Expand All @@ -51,6 +61,16 @@
}
}
},
"Marked as read" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Отмечено прочитанным"
}
}
}
},
"Open" : {
"localizations" : {
"ru" : {
Expand Down
2 changes: 2 additions & 0 deletions Modules/Sources/GalleryFeature/TabViewGallery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public struct TabViewGallery: View {
}
.ignoresSafeArea()
}
.statusBarHidden(!isTouched)
.animation(.easeInOut, value: !isTouched)
.onAppear {
deleteTempFiles()
preloadImage()
Expand Down
8 changes: 8 additions & 0 deletions Modules/Sources/ToastClient/Models/ToastMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ public struct ToastMessage: Equatable, Sendable {
}

public extension ToastMessage {
static let actionCompleted = ToastMessage(
text: LocalizedStringResource("Action completed", bundle: .module),
isError: false,
haptic: .success,
duration: 3,
priority: .low
)

static let whoopsSomethingWentWrong = ToastMessage(
text: LocalizedStringResource("Whoops, something went wrong..", bundle: .module),
isError: true,
Expand Down
10 changes: 10 additions & 0 deletions Modules/Sources/ToastClient/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
{
"sourceLanguage" : "en",
"strings" : {
"Action completed" : {
"localizations" : {
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Действие выполнено"
}
}
}
},
"Whoops, something went wrong.." : {
"localizations" : {
"ru" : {
Expand Down
8 changes: 5 additions & 3 deletions Modules/Sources/TopicFeature/TopicFeature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public struct TopicFeature: Reducer, Sendable {
// MARK: - Localizations

private enum Localization {
static let linkCopied = LocalizedStringResource("Link copied", bundle: .module)
static let favoriteAdded = LocalizedStringResource("Added to favorites", bundle: .module)
static let favoriteRemoved = LocalizedStringResource("Removed from favorites", bundle: .module)
static let postDeleted = LocalizedStringResource("Post deleted", bundle: .module)
Expand Down Expand Up @@ -254,7 +255,9 @@ public struct TopicFeature: Reducer, Sendable {

case .copyLink:
pasteboardClient.copy("https://4pda.to/forum/index.php?showtopic=\(topic.id)")
return .none
return .run { _ in
await toastClient.showToast(ToastMessage(text: Localization.linkCopied, haptic: .success))
}

case .setFavorite:
return .run { [id = state.topicId] send in
Expand Down Expand Up @@ -336,8 +339,7 @@ public struct TopicFeature: Reducer, Sendable {
let link = "https://4pda.to/forum/index.php?showtopic=\(state.topicId)&view=findpost&p=\(postId)"
pasteboardClient.copy(link)
return .run { _ in
let toast = ToastMessage(text: LocalizedStringResource("Link copied", bundle: .module), haptic: .success)
await toastClient.showToast(toast)
await toastClient.showToast(ToastMessage(text: Localization.linkCopied, haptic: .success))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct FormPreviewView: View {
// links will be opening in browser.
}
}
} else {
} else if !store.isPreviewLoading {
Text("Oops, error with loading preview :(", bundle: .module)
.font(.headline)
.foregroundStyle(tintColor)
Expand Down