From d48c1bfff9bc1b7fd58fb5adb6c7d0b4f091605f Mon Sep 17 00:00:00 2001 From: makinosp Date: Tue, 29 Oct 2024 21:31:56 +0900 Subject: [PATCH 01/11] refact: code refactoring --- harmonie/Views/Authentication/OtpView.swift | 2 +- .../Views/Location/LocationCardView.swift | 32 +++++++++---------- harmonie/Views/Location/LocationsView.swift | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/harmonie/Views/Authentication/OtpView.swift b/harmonie/Views/Authentication/OtpView.swift index 3b98a7d..072898e 100644 --- a/harmonie/Views/Authentication/OtpView.swift +++ b/harmonie/Views/Authentication/OtpView.swift @@ -18,7 +18,7 @@ struct OtpView: View { Text("Two-step verification") .font(.headline) VStack { - TextField("Code", text: $code) + TextField(text: $code) { Text(verbatim: "000000") } .multilineTextAlignment(TextAlignment.center) .keyboardType(.decimalPad) .textFieldStyle(.roundedBorder) diff --git a/harmonie/Views/Location/LocationCardView.swift b/harmonie/Views/Location/LocationCardView.swift index 87612f8..2390aa0 100644 --- a/harmonie/Views/Location/LocationCardView.swift +++ b/harmonie/Views/Location/LocationCardView.swift @@ -18,24 +18,22 @@ struct LocationCardView: View { let location: FriendsLocation var body: some View { - Group { - if isFailure { - EmptyView() - } else { - locationCardContent(instance: instance ?? PreviewDataProvider.instance()) - } - } - .redacted(reason: isRequesting ? .placeholder : []) - .task { - if case let .id(id) = location.location { - do { - defer { withAnimation { isRequesting = false } } - let service = appVM.services.instanceService - instance = try await service.fetchInstance(location: id) - } catch { - isFailure = true + if isFailure { + EmptyView() + } else { + locationCardContent(instance: instance ?? PreviewDataProvider.instance()) + .redacted(reason: isRequesting ? .placeholder : []) + .task { + if case let .id(id) = location.location { + do { + defer { withAnimation { isRequesting = false } } + let service = appVM.services.instanceService + instance = try await service.fetchInstance(location: id) + } catch { + isFailure = true + } + } } - } } } diff --git a/harmonie/Views/Location/LocationsView.swift b/harmonie/Views/Location/LocationsView.swift index 0d63194..2c063aa 100644 --- a/harmonie/Views/Location/LocationsView.swift +++ b/harmonie/Views/Location/LocationsView.swift @@ -96,7 +96,7 @@ struct LocationsView: View { .setColumn() } - @ViewBuilder private var friendLocations: some View { + private var friendLocations: some View { Section { if friendVM.isFetchingAllFriends { ForEach(0...7, id: \.self) { _ in From 903b905ca2646925899f44d3eb9d1289f0d5eb4c Mon Sep 17 00:00:00 2001 From: makinosp Date: Tue, 29 Oct 2024 21:32:18 +0900 Subject: [PATCH 02/11] update: localization --- harmonie/Localization/Localizable.xcstrings | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/harmonie/Localization/Localizable.xcstrings b/harmonie/Localization/Localizable.xcstrings index 17c18ec..f9e294f 100644 --- a/harmonie/Localization/Localizable.xcstrings +++ b/harmonie/Localization/Localizable.xcstrings @@ -223,22 +223,6 @@ } } }, - "Code" : { - "localizations" : { - "ja" : { - "stringUnit" : { - "state" : "translated", - "value" : "コード" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "代码" - } - } - } - }, "Confirm" : { "localizations" : { "ja" : { From 38d7ec0c78c89c425c96cdc33e2af0b14f08d9d8 Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 21:39:57 +0900 Subject: [PATCH 03/11] refact: remove unnecessary code --- harmonie/Views/Location/LocationDetailView.swift | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/harmonie/Views/Location/LocationDetailView.swift b/harmonie/Views/Location/LocationDetailView.swift index e816b1f..d01dc38 100644 --- a/harmonie/Views/Location/LocationDetailView.swift +++ b/harmonie/Views/Location/LocationDetailView.swift @@ -62,17 +62,6 @@ struct LocationDetailView: View { .navigationBarTitleDisplayMode(.inline) } - private var bottomBar: some View { - VStack(alignment: .leading) { - Text(instance.world.name) - .font(.headline) - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.vertical, 8) - .padding(.horizontal, 12) - .foregroundStyle(Color.white) - } - private var friendList: ForEach<[Friend], Friend.ID, some View> { ForEach(location.friends) { friend in NavigationLabel { From 259044405b9ed331c1037419d638613272149ff7 Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 22:33:25 +0900 Subject: [PATCH 04/11] feat: make InstanceLocation.instance optional --- harmonie/Models/InstanceLocationModel.swift | 10 +++++++++- harmonie/Views/Location/LocationDetailView.swift | 6 ++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/harmonie/Models/InstanceLocationModel.swift b/harmonie/Models/InstanceLocationModel.swift index 218084a..fb2f290 100644 --- a/harmonie/Models/InstanceLocationModel.swift +++ b/harmonie/Models/InstanceLocationModel.swift @@ -9,9 +9,17 @@ import VRCKit struct InstanceLocation: Hashable { let location: FriendsLocation - let instance: Instance + let instance: Instance? } extension InstanceLocation: Identifiable { var id: Int { hashValue } } + +extension InstanceLocation { + /// Initialize as private instance + init(friends: [Friend]) { + let location = FriendsLocation(location: .private, friends: friends) + self.init(location: location, instance: nil) + } +} diff --git a/harmonie/Views/Location/LocationDetailView.swift b/harmonie/Views/Location/LocationDetailView.swift index d01dc38..8627660 100644 --- a/harmonie/Views/Location/LocationDetailView.swift +++ b/harmonie/Views/Location/LocationDetailView.swift @@ -14,10 +14,8 @@ import VRCKit struct LocationDetailView: View { @InitWrapper(.internal, type: Binding) @Binding private var selection: SegmentIdSelection? - @Init(.internal) private let instanceLocation: InstanceLocation - - private var location: FriendsLocation { instanceLocation.location } - private var instance: Instance { instanceLocation.instance } + @Init(.internal) private let location: FriendsLocation + @Init(.internal) private let instance: Instance private typealias InformationItem = (title: String, value: String) private var information: [InformationItem] { From 2946365c6094d9e0932cdb9a5c82c29802893381 Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 22:53:08 +0900 Subject: [PATCH 05/11] feat: implement private location friends view --- harmonie/Views/Location/LocationsView.swift | 12 +++--- .../Views/Location/PrivateLocationView.swift | 37 +++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 harmonie/Views/Location/PrivateLocationView.swift diff --git a/harmonie/Views/Location/LocationsView.swift b/harmonie/Views/Location/LocationsView.swift index 2c063aa..40a9b44 100644 --- a/harmonie/Views/Location/LocationsView.swift +++ b/harmonie/Views/Location/LocationsView.swift @@ -13,6 +13,7 @@ struct LocationsView: View { @Environment(FriendViewModel.self) var friendVM @State private var columnVisibility: NavigationSplitViewVisibility = .all @State private var selectedInstance: InstanceLocation? + @State private var isSelectedPrivate = false @State private var selection: SegmentIdSelection? var body: some View { @@ -53,11 +54,11 @@ struct LocationsView: View { private var content: some View { Group { - if let selectedInstance = selectedInstance { - LocationDetailView( - selection: $selection, - instanceLocation: selectedInstance - ) + if let location = selectedInstance?.location, + let instance = selectedInstance?.instance { + LocationDetailView(selection: $selection, location: location, instance: instance) + } else if let instance = selectedInstance, instance.location.location == .private { + PrivateLocationView($selection, friends: instance.location.friends) } } .overlay { @@ -143,6 +144,7 @@ struct LocationsView: View { } .padding(.top, 4) } + .tag(InstanceLocation(friends: friendVM.friendsInPrivate)) } } } diff --git a/harmonie/Views/Location/PrivateLocationView.swift b/harmonie/Views/Location/PrivateLocationView.swift new file mode 100644 index 0000000..2d21002 --- /dev/null +++ b/harmonie/Views/Location/PrivateLocationView.swift @@ -0,0 +1,37 @@ +// +// PrivateLocationView.swift +// Harmonie +// +// Created by makinosp on 2024/10/30. +// + +import MemberwiseInit +import SwiftUI +import VRCKit + +@MemberwiseInit +struct PrivateLocationView: View { + @InitWrapper(.internal, label: "_", type: Binding) + @Binding private var selection: SegmentIdSelection? + @Init(.internal) private let friends: [Friend] + + var body: some View { + List(selection: $selection) { + Section("Friends") { + ForEach(friends) { friend in + NavigationLabel { + Label { + Text(friend.displayName) + } icon: { + UserIcon(user: friend, size: Constants.IconSize.thumbnail) + } + } + .tag(SegmentIdSelection(friendId: friend.id)) + } + } + } + .listStyle(.insetGrouped) + .navigationTitle("Private") + .navigationBarTitleDisplayMode(.inline) + } +} From 8ac33a228f444e5ab43d4f97811bc255a8b00870 Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 22:54:20 +0900 Subject: [PATCH 06/11] refact: code refactoring --- harmonie/Views/Location/LocationDetailView.swift | 2 +- harmonie/Views/Location/LocationsView.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/harmonie/Views/Location/LocationDetailView.swift b/harmonie/Views/Location/LocationDetailView.swift index 8627660..e6cab05 100644 --- a/harmonie/Views/Location/LocationDetailView.swift +++ b/harmonie/Views/Location/LocationDetailView.swift @@ -12,7 +12,7 @@ import VRCKit @MemberwiseInit struct LocationDetailView: View { - @InitWrapper(.internal, type: Binding) + @InitWrapper(.internal, label: "_", type: Binding) @Binding private var selection: SegmentIdSelection? @Init(.internal) private let location: FriendsLocation @Init(.internal) private let instance: Instance diff --git a/harmonie/Views/Location/LocationsView.swift b/harmonie/Views/Location/LocationsView.swift index 40a9b44..fca3cca 100644 --- a/harmonie/Views/Location/LocationsView.swift +++ b/harmonie/Views/Location/LocationsView.swift @@ -56,7 +56,7 @@ struct LocationsView: View { Group { if let location = selectedInstance?.location, let instance = selectedInstance?.instance { - LocationDetailView(selection: $selection, location: location, instance: instance) + LocationDetailView($selection, location: location, instance: instance) } else if let instance = selectedInstance, instance.location.location == .private { PrivateLocationView($selection, friends: instance.location.friends) } From ab44a14bff014097675fb7486c48e2cc53f121ef Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 22:54:38 +0900 Subject: [PATCH 07/11] update: localization --- Harmonie.xcodeproj/project.pbxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Harmonie.xcodeproj/project.pbxproj b/Harmonie.xcodeproj/project.pbxproj index f24a272..1f47621 100644 --- a/Harmonie.xcodeproj/project.pbxproj +++ b/Harmonie.xcodeproj/project.pbxproj @@ -237,6 +237,7 @@ en, ja, "zh-Hans", + Base, ); mainGroup = 20395D882B945CD700003921; packageReferences = ( From 88e3fb68dc96a1c3f155fe73cb547e8658c884ce Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 23:14:16 +0900 Subject: [PATCH 08/11] feat: improvement FavoriteGroupListView, FavoriteGroupEditView --- .../FavoriteType+LocalizedStringKey.swift | 22 +++++++++++++++++++ .../FavoriteGroupsEditView.swift | 5 +++++ .../FavoriteGroupsListView.swift | 3 ++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 harmonie/Extensions/FavoriteType+LocalizedStringKey.swift diff --git a/harmonie/Extensions/FavoriteType+LocalizedStringKey.swift b/harmonie/Extensions/FavoriteType+LocalizedStringKey.swift new file mode 100644 index 0000000..523d755 --- /dev/null +++ b/harmonie/Extensions/FavoriteType+LocalizedStringKey.swift @@ -0,0 +1,22 @@ +// +// FavoriteType+LocalizedStringKey.swift +// Harmonie +// +// Created by makinosp on 2024/10/30. +// + +import VRCKit +import SwiftUICore + +extension FavoriteType { + var localizedStringKey: LocalizedStringKey { + switch self { + case .world: + LocalizedStringKey("World") + case .avatar: + LocalizedStringKey("Avatar") + case .friend: + LocalizedStringKey("Friend") + } + } +} diff --git a/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsEditView.swift b/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsEditView.swift index 1ee13b5..495f140 100644 --- a/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsEditView.swift +++ b/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsEditView.swift @@ -12,6 +12,7 @@ struct FavoriteGroupsEditView: View { @Environment(AppViewModel.self) var appVM @Environment(FavoriteViewModel.self) var favoriteVM @Environment(\.dismiss) private var dismiss + @FocusState var isFocusedTextField @State private var displayName: String @State private var visibility: FavoriteGroup.Visibility @State private var isRequesting = false @@ -28,10 +29,14 @@ struct FavoriteGroupsEditView: View { Form { Section("Display Name") { TextField("", text: $displayName) + .focused($isFocusedTextField) } } .toolbar { toolbarItems } } + .task { + isFocusedTextField = true + } } @ToolbarContentBuilder var toolbarItems: some ToolbarContent { diff --git a/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsListView.swift b/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsListView.swift index dfecb13..1c66351 100644 --- a/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsListView.swift +++ b/harmonie/Views/Setting/FavoriteGroups/FavoriteGroupsListView.swift @@ -16,7 +16,7 @@ struct FavoriteGroupsListView: View { List { let types: [FavoriteType] = [.friend, .world] ForEach(types, id: \.hashValue) { type in - Section(type.rawValue) { + Section(type.localizedStringKey) { ForEach(favoriteVM.favoriteGroups(type)) { group in Button { selected = group @@ -30,6 +30,7 @@ struct FavoriteGroupsListView: View { } .sheet(item: $selected) { group in FavoriteGroupsEditView(favoriteGroup: group) + .presentationDetents([.small]) } .navigationTitle("Edit favorite groups") .navigationBarTitleDisplayMode(.inline) From 50f0caa19f14a43fac4c1ad5aa10bab66554527a Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 23:14:25 +0900 Subject: [PATCH 09/11] update: localizatoin --- harmonie/Localization/Localizable.xcstrings | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/harmonie/Localization/Localizable.xcstrings b/harmonie/Localization/Localizable.xcstrings index f9e294f..a7ac12d 100644 --- a/harmonie/Localization/Localizable.xcstrings +++ b/harmonie/Localization/Localizable.xcstrings @@ -143,6 +143,22 @@ } } }, + "Avatar" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "アバター" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "模型" + } + } + } + }, "Build" : { "localizations" : { "ja" : { @@ -528,6 +544,22 @@ } } }, + "Friend" : { + "localizations" : { + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "フレンド" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "好友" + } + } + } + }, "Friend Locations" : { "localizations" : { "ja" : { From 7ae373926f7f446488316c8d93dd13ff1b6a78f1 Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 23:14:36 +0900 Subject: [PATCH 10/11] refact: code refactoring --- harmonie/Views/UserDetail/NoteEditView.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/harmonie/Views/UserDetail/NoteEditView.swift b/harmonie/Views/UserDetail/NoteEditView.swift index 7ba1661..a9361f0 100644 --- a/harmonie/Views/UserDetail/NoteEditView.swift +++ b/harmonie/Views/UserDetail/NoteEditView.swift @@ -11,7 +11,7 @@ import VRCKit struct NoteEditView: View { @Environment(AppViewModel.self) var appVM @Environment(\.dismiss) private var dismiss - @FocusState var isFocusedNoteField + @FocusState var isFocusedTextField @State private var text: String @State private var isRequesting = false private let userId: String @@ -28,7 +28,7 @@ struct NoteEditView: View { Form { TextField("Enter note", text: $text, axis: .vertical) .lineLimit(5...10) - .focused($isFocusedNoteField) + .focused($isFocusedTextField) } .scrollDisabled(true) .contentMargins(.vertical, .zero) @@ -37,7 +37,7 @@ struct NoteEditView: View { .navigationBarTitleDisplayMode(.inline) } .task { - isFocusedNoteField = true + isFocusedTextField = true } } From c4a95240a040600803e680a91386fc5683f1b46f Mon Sep 17 00:00:00 2001 From: makinosp Date: Wed, 30 Oct 2024 23:22:06 +0900 Subject: [PATCH 11/11] update: bump up to 0.9.6 --- Harmonie.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Harmonie.xcodeproj/project.pbxproj b/Harmonie.xcodeproj/project.pbxproj index 1f47621..6fbe685 100644 --- a/Harmonie.xcodeproj/project.pbxproj +++ b/Harmonie.xcodeproj/project.pbxproj @@ -474,7 +474,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.9.5; + MARKETING_VERSION = 0.9.6; PRODUCT_BUNDLE_IDENTIFIER = jp.mknn.harmonie; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; @@ -510,7 +510,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.9.5; + MARKETING_VERSION = 0.9.6; PRODUCT_BUNDLE_IDENTIFIER = jp.mknn.harmonie; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES;