diff --git a/PrivacyPolicy.md b/PrivacyPolicy.md new file mode 100644 index 0000000..a481cef --- /dev/null +++ b/PrivacyPolicy.md @@ -0,0 +1,18 @@ +# Privacy Policy + +## About the App + +This application is a tool that uses the VRChat Web API to display and manage information related to VRChat accounts. The app respects user privacy and operates in accordance with the policies outlined below. + +## Collection of Personal Information + +This application does not collect, store, or share any personal information from users. All data is obtained through the VRChat Web API and used only within the app. + +## Handling of Authentication Information + +The app uses VRChat authentication tokens to access the API. These tokens are securely stored on the device and are not shared with any third parties. + +## VRChat Privacy Policy + +When using the VRChat API, users must comply with VRChat’s Privacy Policy. Please refer to the following link for details: +[VRChat Privacy Policy](https://hello.vrchat.com/privacy) diff --git a/harmonie/Components/GeometricScreen.swift b/harmonie/Components/GeometricScreen.swift new file mode 100644 index 0000000..c60193b --- /dev/null +++ b/harmonie/Components/GeometricScreen.swift @@ -0,0 +1,33 @@ +// +// GeometricScreen.swift +// Harmonie +// +// Created by makinosp on 2024/11/15. +// + +import SwiftUICore + +struct GeometricScreen: View where Content: View { + private let content: () -> Content + private let action: (_ geometry: GeometryProxy) -> Void + + init( + @ViewBuilder content: @escaping () -> Content, + action: @escaping (_ geometry: GeometryProxy) -> Void + ) { + self.content = content + self.action = action + } + + var body: some View { + GeometryReader { geometry in + content() + .onChange(of: geometry) { + action(geometry) + } + .onAppear { + action(geometry) + } + } + } +} diff --git a/harmonie/Views/ContentView.swift b/harmonie/Views/ContentView.swift index 7ca52bf..3681cf6 100644 --- a/harmonie/Views/ContentView.swift +++ b/harmonie/Views/ContentView.swift @@ -14,29 +14,23 @@ struct ContentView: View { @Environment(FavoriteViewModel.self) var favoriteVM: FavoriteViewModel var body: some View { - GeometryReader { geometry in - Group { - switch appVM.step { - case .initializing: - ProgressScreen() - .task { - appVM.step = await appVM.setup(service: appVM.services.authenticationService) - } - .errorAlert() - case .loggingIn: - LoginView() - .errorAlert() - case .done: - MainTabView() - .errorAlert() - } - } - .onChange(of: geometry) { - setScreenSize(geometry) - } - .onAppear { - setScreenSize(geometry) + GeometricScreen { + switch appVM.step { + case .initializing: + ProgressScreen() + .task { + appVM.step = await appVM.setup(service: appVM.services.authenticationService) + } + .errorAlert() + case .loggingIn: + LoginView() + .errorAlert() + case .done: + MainTabView() + .errorAlert() } + } action: { geometry in + setScreenSize(geometry) } } diff --git a/harmonie/Views/Location/LocationsView.swift b/harmonie/Views/Location/LocationsView.swift index 0104ebd..df9f0fa 100644 --- a/harmonie/Views/Location/LocationsView.swift +++ b/harmonie/Views/Location/LocationsView.swift @@ -86,6 +86,7 @@ struct LocationsView: View { } } } + .safeAreaPadding(.top, 20) .background(Color(.systemGroupedBackground)) .setColumn(appVM.screenSize) } diff --git a/harmonie/Views/MainTabView.swift b/harmonie/Views/MainTabView.swift index a7a14b4..0b816be 100644 --- a/harmonie/Views/MainTabView.swift +++ b/harmonie/Views/MainTabView.swift @@ -10,6 +10,7 @@ import VRCKit struct MainTabView: View { @Environment(\.scenePhase) var scenePhase + @Environment(\.horizontalSizeClass) var defaultHorizontalSizeClass @Environment(AppViewModel.self) var appVM: AppViewModel @Environment(FriendViewModel.self) var friendVM: FriendViewModel @Environment(FavoriteViewModel.self) var favoriteVM: FavoriteViewModel @@ -48,15 +49,6 @@ extension MainTabViewSegment { case .settings: SettingsView() } } - - var label: Label { - Label(description, systemImage: icon.systemName) - } - - @available(iOS 18, *) - var tab: some TabContent { - Tab(description, systemImage: icon.systemName, value: self) { content } - } } @MainActor @@ -85,7 +77,10 @@ extension MainTabView { tabSegment.content .tag(tabSegment) .tabItem { - tabSegment.label + Label( + tabSegment.description, + systemImage: tabSegment.icon.systemName + ) } } } @@ -93,9 +88,14 @@ extension MainTabView { @available(iOS 18, *) private var tabView: some View { TabView(selection: $selection) { - return ForEach(MainTabViewSegment.allCases) { $0.tab } + ForEach(MainTabViewSegment.allCases) { segment in + Tab(segment.description, systemImage: segment.icon.systemName, value: segment) { + segment.content.environment(\.horizontalSizeClass, defaultHorizontalSizeClass) + } + } } .tabViewStyle(.sidebarAdaptable) + .environment(\.horizontalSizeClass, .compact) } private func fetchFriendsTask() async {