Skip to content

Commit

Permalink
Merge pull request #86 from day-23/dev
Browse files Browse the repository at this point in the history
release: Version 1.0.5
  • Loading branch information
cjeongmin authored Dec 16, 2023
2 parents d6efa48 + 3a0473a commit 3d97c2c
Show file tree
Hide file tree
Showing 56 changed files with 1,568 additions and 1,102 deletions.
18 changes: 18 additions & 0 deletions Flux/Action.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Action.swift
// Haru
//
// Created by 최정민 on 11/19/23.
//

import Foundation

final class Action<T> {
private(set) var key: String
private(set) var updater: (T) -> T

init(key: String, updater: @escaping (T) -> T) {
self.key = key
self.updater = updater
}
}
86 changes: 86 additions & 0 deletions Flux/Dispatcher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// Dispatcher.swift
// Haru
//
// Created by 최정민 on 11/19/23.
//

import Foundation

final class FluxDispatcher {
private init() {}
public static let `default`: FluxDispatcher = .init()

private var stores: [String: Any] = [:]

public func register<T, A: Action>(store: Store<T, A>) {
if stores.keys.contains(store.id) {
return
}

stores[store.id] = store
}

public func unregister(storeId id: String) {
stores.removeValue(forKey: id)
}

public func get<T, A: Action>(
for type: T.Type,
actionType: A.Type) -> [Store<T, A>]
{
var res: [Store<T, A>] = []

for store in stores.values {
if let store = store as? Store<T, A> {
res.append(store)
}
}

return res
}

public func get<T, A: Action>(
storeId id: String,
for type: T.Type,
actionType: A.Type) -> Store<T, A>?
{
for store in get(for: type, actionType: actionType) {
if store.id == id {
return store
}
}

return nil
}

public func dispatch<T, A: Action>(
action: A,
params: UpdaterParameters = [:],
for type: T.Type)
{
for store in stores.values {
if let store = store as? Store<T, A> {
store.update(action: action, params: params)
}
}
}

public func dispatch<T, A: Action>(
action: A,
params: UpdaterParameters = [:],
storeId id: String,
for type: T.Type)
{
for store in stores.values {
if let store = store as? Store<T, A> {
if store.id == id {
store.update(action: action, params: params)
return
}
}
}
}
}

let Dispatcher = FluxDispatcher.default
20 changes: 20 additions & 0 deletions Flux/Reducer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Reducer.swift
// Haru
//
// Created by 최정민 on 11/20/23.
//

import Foundation

final class Reducer<T> {
private(set) var actions: Action<T>

init(actions: Action<T>) {
self.actions = actions
}

public func update(key: String) {
switch key {}
}
}
33 changes: 33 additions & 0 deletions Flux/Store.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// Store.swift
// Haru
//
// Created by 최정민 on 11/19/23.
//

import Foundation

typealias Action = Hashable & RawRepresentable
typealias UpdaterParameters = Any
typealias Updater<T> = (T, UpdaterParameters) -> T
typealias Reducer<T, A: Action> = [A: Updater<T>]

final class Store<T, A: Action>: ObservableObject {
public let id: String
@Published private(set) var state: T
private(set) var reducer: Reducer<T, A> = [:]

public func update(action: A, params: UpdaterParameters) {
guard let updater = reducer[action] else {
return
}

state = updater(state, params)
}

init(id: String = UUID().uuidString, initialState state: T, reducer: [A: Updater<T>]) {
self.id = id
self.state = state
self.reducer = reducer
}
}
32 changes: 30 additions & 2 deletions Haru.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
130667CB29CEE38500AACEE6 /* SwiftUIPager in Frameworks */ = {isa = PBXBuildFile; productRef = 130667CA29CEE38500AACEE6 /* SwiftUIPager */; };
131CFCA32A6133E400C813C3 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 131CFCA22A6133E400C813C3 /* Kingfisher */; };
131CFCA52A6143D400C813C3 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131CFCA42A6143D400C813C3 /* URL.swift */; };
133FF36D2AF20D55004D46BE /* AFProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133FF36C2AF20D55004D46BE /* AFProxy.swift */; };
1342D4DC2A1F7A74006758E9 /* SignUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1342D4DB2A1F7A74006758E9 /* SignUpView.swift */; };
1342D4DE2A1FBDB0006758E9 /* SettingHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1342D4DD2A1FBDB0006758E9 /* SettingHeader.swift */; };
1342D4E02A1FBE87006758E9 /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1342D4DF2A1FBE87006758E9 /* AccountView.swift */; };
Expand All @@ -101,6 +102,8 @@
134F5FF429DF1FF90072704B /* TimeTableTodoRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134F5FF329DF1FF90072704B /* TimeTableTodoRow.swift */; };
134F5FF629DF20160072704B /* TimeTableTodoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 134F5FF529DF20160072704B /* TimeTableTodoItem.swift */; };
1356621829D1EE29003CAD1B /* DefaultTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1356621729D1EE29003CAD1B /* DefaultTag.swift */; };
135E92FC2B0A3E2800C51986 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135E92FB2B0A3E2800C51986 /* Store.swift */; };
135E92FE2B0A3E2F00C51986 /* Dispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 135E92FD2B0A3E2F00C51986 /* Dispatcher.swift */; };
1369CD562A291BF000B8B420 /* WithdrawalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1369CD552A291BF000B8B420 /* WithdrawalView.swift */; };
137815A92A32FAFB0050F3C3 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137815A82A32FAFA0050F3C3 /* LoadingView.swift */; };
137815AB2A338ED10050F3C3 /* SettingUserInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 137815AA2A338ED10050F3C3 /* SettingUserInfoView.swift */; };
Expand All @@ -112,6 +115,8 @@
139224202A20C532002894B2 /* UserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1392241F2A20C532002894B2 /* UserService.swift */; };
139224282A210340002894B2 /* CustomTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139224272A210340002894B2 /* CustomTabView.swift */; };
1392242A2A210AE3002894B2 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139224292A210AE3002894B2 /* Tab.swift */; };
1393DF7E2B2DC4CA00771E5B /* PrivacyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1393DF7D2B2DC4CA00771E5B /* PrivacyViewModel.swift */; };
1393DF802B2DE19A00771E5B /* SettingAlarmViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1393DF7F2B2DE19A00771E5B /* SettingAlarmViewModel.swift */; };
1396D3412A3F744D0040946B /* HapticManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1396D3402A3F744D0040946B /* HapticManager.swift */; };
139F99632A0BA12500BD56C7 /* RepeatAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139F99622A0BA12500BD56C7 /* RepeatAt.swift */; };
13A57DBD2A13587E0010A481 /* TodoState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13A57DBC2A13587E0010A481 /* TodoState.swift */; };
Expand Down Expand Up @@ -298,6 +303,7 @@
130667AC29CEE1FE00AACEE6 /* Calendar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Calendar.swift; sourceTree = "<group>"; };
130667B229CEE20A00AACEE6 /* CalendarHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarHelper.swift; sourceTree = "<group>"; };
131CFCA42A6143D400C813C3 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
133FF36C2AF20D55004D46BE /* AFProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AFProxy.swift; sourceTree = "<group>"; };
1342D4DB2A1F7A74006758E9 /* SignUpView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpView.swift; sourceTree = "<group>"; };
1342D4DD2A1FBDB0006758E9 /* SettingHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingHeader.swift; sourceTree = "<group>"; };
1342D4DF2A1FBE87006758E9 /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = "<group>"; };
Expand All @@ -308,6 +314,8 @@
134F5FF329DF1FF90072704B /* TimeTableTodoRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTableTodoRow.swift; sourceTree = "<group>"; };
134F5FF529DF20160072704B /* TimeTableTodoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTableTodoItem.swift; sourceTree = "<group>"; };
1356621729D1EE29003CAD1B /* DefaultTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTag.swift; sourceTree = "<group>"; };
135E92FB2B0A3E2800C51986 /* Store.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = "<group>"; };
135E92FD2B0A3E2F00C51986 /* Dispatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dispatcher.swift; sourceTree = "<group>"; };
1369CD552A291BF000B8B420 /* WithdrawalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithdrawalView.swift; sourceTree = "<group>"; };
137414BC29CEE5A7005A8282 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
137815A82A32FAFA0050F3C3 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; };
Expand All @@ -320,6 +328,8 @@
1392241F2A20C532002894B2 /* UserService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserService.swift; sourceTree = "<group>"; };
139224272A210340002894B2 /* CustomTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTabView.swift; sourceTree = "<group>"; };
139224292A210AE3002894B2 /* Tab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tab.swift; sourceTree = "<group>"; };
1393DF7D2B2DC4CA00771E5B /* PrivacyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyViewModel.swift; sourceTree = "<group>"; };
1393DF7F2B2DE19A00771E5B /* SettingAlarmViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingAlarmViewModel.swift; sourceTree = "<group>"; };
1396D3402A3F744D0040946B /* HapticManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticManager.swift; sourceTree = "<group>"; };
139F99622A0BA12500BD56C7 /* RepeatAt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatAt.swift; sourceTree = "<group>"; };
13A57DBC2A13587E0010A481 /* TodoState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodoState.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -445,6 +455,7 @@
isa = PBXGroup;
children = (
130666CA29CEDF4A00AACEE6 /* Haru */,
135E92FA2B0A3DEC00C51986 /* Flux */,
130666C929CEDF4A00AACEE6 /* Products */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -559,6 +570,7 @@
6F0B0F762A0E9FE00003F313 /* CommentService.swift */,
6F0649432A2A4DDE001C88B3 /* SearchService.swift */,
13E976BB2A3C3A6D00D1870F /* ApiRequestInterceptor.swift */,
133FF36C2AF20D55004D46BE /* AFProxy.swift */,
);
path = Services;
sourceTree = "<group>";
Expand Down Expand Up @@ -597,6 +609,8 @@
6F0B0F782A0EABC00003F313 /* CommentFormViewModel.swift */,
6F61A95E2A24935A002609D6 /* CommentViewModel.swift */,
6F0649452A2A4FBE001C88B3 /* SearchViewModel.swift */,
1393DF7D2B2DC4CA00771E5B /* PrivacyViewModel.swift */,
1393DF7F2B2DE19A00771E5B /* SettingAlarmViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
Expand Down Expand Up @@ -737,6 +751,15 @@
path = CheckList;
sourceTree = "<group>";
};
135E92FA2B0A3DEC00C51986 /* Flux */ = {
isa = PBXGroup;
children = (
135E92FB2B0A3E2800C51986 /* Store.swift */,
135E92FD2B0A3E2F00C51986 /* Dispatcher.swift */,
);
path = Flux;
sourceTree = "<group>";
};
13A57DC02A1359430010A481 /* State */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -924,6 +947,7 @@
6F9693742A57E86D00BE8B62 /* GIFImage.swift in Sources */,
130667AD29CEE1FE00AACEE6 /* RepeatOption.swift in Sources */,
13A57DBF2A1358B40010A481 /* ScheduleState.swift in Sources */,
135E92FC2B0A3E2800C51986 /* Store.swift in Sources */,
1306671D29CEE14000AACEE6 /* TagService.swift in Sources */,
6F86EF1E29D0EBCA002436A5 /* AlarmOption.swift in Sources */,
AE5085B72A16B21100A373BC /* AuthService.swift in Sources */,
Expand Down Expand Up @@ -956,6 +980,7 @@
1306676429CEE19C00AACEE6 /* CalendarDateItem.swift in Sources */,
130667A429CEE1F200AACEE6 /* Date.swift in Sources */,
6F360A132A13AA4C00D64BB6 /* HashTag.swift in Sources */,
133FF36D2AF20D55004D46BE /* AFProxy.swift in Sources */,
6F54DF5929DD919C002FAD7F /* ProfileFormView.swift in Sources */,
6FB144FD2A0A87D9006EA177 /* FriendService.swift in Sources */,
6F360A152A15EC9C00D64BB6 /* MediaListView.swift in Sources */,
Expand Down Expand Up @@ -989,6 +1014,7 @@
6F0649442A2A4DDE001C88B3 /* SearchService.swift in Sources */,
13D9B5AD29D5DDA100109C0E /* TimeTableTodoView.swift in Sources */,
1306671529CEE13200AACEE6 /* Alarm.swift in Sources */,
135E92FE2B0A3E2F00C51986 /* Dispatcher.swift in Sources */,
1306671029CEE13200AACEE6 /* Schedule.swift in Sources */,
1392241C2A20A765002894B2 /* ScreenView.swift in Sources */,
13FAE4402A1DD32D007C3C5D /* MyView.swift in Sources */,
Expand All @@ -997,6 +1023,7 @@
AE5085B92A16B44200A373BC /* Auth.swift in Sources */,
1306671129CEE13200AACEE6 /* Event.swift in Sources */,
1306677529CEE19C00AACEE6 /* ListSectionView.swift in Sources */,
1393DF7E2B2DC4CA00771E5B /* PrivacyViewModel.swift in Sources */,
13E294C22A272FDB00279F4D /* AlarmHelper.swift in Sources */,
6F54DF4B29DC813D002FAD7F /* MediaView.swift in Sources */,
6F9C740C2A27803900C04788 /* FriendUser.swift in Sources */,
Expand Down Expand Up @@ -1095,6 +1122,7 @@
130666FC29CEE0AC00AACEE6 /* Constants.swift in Sources */,
6F61A95B2A246C79002609D6 /* KeyboardReadable.swift in Sources */,
1306678229CEE1D300AACEE6 /* ScheduleFormViewModel.swift in Sources */,
1393DF802B2DE19A00771E5B /* SettingAlarmViewModel.swift in Sources */,
6F9C740A2A276E5F00C04788 /* FriendOption.swift in Sources */,
13DE94BA2A16848700D43105 /* SplashView.swift in Sources */,
);
Expand Down Expand Up @@ -1244,7 +1272,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.4;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = day23.Haru;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand Down Expand Up @@ -1283,7 +1311,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.4;
MARKETING_VERSION = 1.0.5;
PRODUCT_BUNDLE_IDENTIFIER = day23.Haru;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand Down
6 changes: 4 additions & 2 deletions Haru/Components/Modal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,14 @@ struct Modal<Content>: View where Content: View {
.transition(.move(edge: .bottom))
.onAppear {
withAnimation(.easeInOut(duration: 0.25)) {
Global.shared.isTabViewActive = false
Dispatcher.dispatch(action: Global.Actions.setIsTabViewActive,
params: false, storeId: "global", for: Global.self)
}
}
.onDisappear {
withAnimation(.easeInOut(duration: 0.25)) {
Global.shared.isTabViewActive = true
Dispatcher.dispatch(action: Global.Actions.setIsTabViewActive,
params: true, storeId: "global", for: Global.self)
}
modalOffset = .zero
}
Expand Down
9 changes: 6 additions & 3 deletions Haru/Components/PopupImagePicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,13 @@ struct PopupImagePicker: View {
if imagePickerModel.fetchedImages.firstIndex(where: { $0.id == imageAsset.id })
== imagePickerModel.fetchedImages.count - 1
{
Global.shared.toastMessageContent = "최근 \(min(200, imagePickerModel.fetchedImages.count))개의 사진을 모두 불러 왔습니다."
Global.shared.toastMessageTheme = .dark
withAnimation {
Global.shared.showToastMessage = true
Dispatcher.dispatch(action: Global.Actions.showToastMessage,
params: [
"message": "최근 \(min(200, imagePickerModel.fetchedImages.count))개의 사진을 모두 불러 왔습니다.",
"theme": Global.ToastMessageTheme.dark,
],
storeId: "global", for: Global.self)
}
}
}
Expand Down
Loading

0 comments on commit 3d97c2c

Please sign in to comment.