Skip to content

Commit

Permalink
Merge pull request #171 from makinosp/develop
Browse files Browse the repository at this point in the history
update: bump up to 0.9.4
  • Loading branch information
makinosp authored Oct 20, 2024
2 parents 76580e0 + 0ddee7d commit cd6b883
Show file tree
Hide file tree
Showing 18 changed files with 189 additions and 168 deletions.
4 changes: 2 additions & 2 deletions Harmonie.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.9.3;
MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = jp.mknn.harmonie;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down Expand Up @@ -509,7 +509,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.9.3;
MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = jp.mknn.harmonie;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
26 changes: 7 additions & 19 deletions harmonie/Components/SquareURLImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,17 @@
//

import NukeUI
import MemberwiseInit
import SwiftUI

@MemberwiseInit
struct SquareURLImage: View {
@State private var isImageLoaded = false
private let imageUrl: URL?
private let thumbnailImageUrl: URL?
private let frameWidth: CGFloat
private let cornerRadius: CGFloat
private let ratio: CGFloat

init(
imageUrl: URL?,
thumbnailImageUrl: URL? = nil,
frameWidth: CGFloat = 100,
ratio: CGFloat = 3/4,
cornerRadius: CGFloat = 4
) {
self.imageUrl = imageUrl
self.thumbnailImageUrl = thumbnailImageUrl
self.frameWidth = frameWidth
self.cornerRadius = cornerRadius
self.ratio = ratio
}
@Init(.internal) private let imageUrl: URL?
@Init(.internal, default: nil) private let thumbnailImageUrl: URL?
@Init(.internal, default: 100) private let frameWidth: CGFloat
@Init(.internal, default: 4) private let cornerRadius: CGFloat
@Init(.internal, default: 3/4) private let ratio: CGFloat

var rect: some Shape {
RoundedRectangle(cornerRadius: cornerRadius)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
//
// NSError+isCancelled.swift
// Error+isCancelled.swift
// Harmonie
//
// Created by makinosp on 2024/09/08.
//

import Foundation

extension Error {
var isCancelled: Bool {
(self as NSError?)?.isCancelled ?? false
}
}

extension NSError {
/// A Boolean value indicating whether the error represents a cancelled network request.
var isCancelled: Bool {
Expand Down
42 changes: 23 additions & 19 deletions harmonie/Localization/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,6 @@
}
}
},
"All" : {
"localizations" : {
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "全て"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "全部"
}
}
}
},
"App Name" : {
"localizations" : {
"ja" : {
Expand Down Expand Up @@ -568,7 +552,7 @@
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "フレンドのロケーション"
"value" : "フレンドの現在地"
}
},
"zh-Hans" : {
Expand Down Expand Up @@ -763,7 +747,7 @@
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロケーション"
"value" : "現在地"
}
},
"zh-Hans" : {
Expand Down Expand Up @@ -954,6 +938,16 @@
}
}
},
"Opening URL" : {
"localizations" : {
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "URLを開く"
}
}
}
},
"Password" : {
"localizations" : {
"ja" : {
Expand Down Expand Up @@ -1119,7 +1113,7 @@
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "ロケーションを選択"
"value" : "現在地を選択"
}
},
"zh-Hans" : {
Expand Down Expand Up @@ -1290,6 +1284,16 @@
}
}
},
"The URL below will be opened" : {
"localizations" : {
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "下記のURLを開きます"
}
}
}
},
"Third Party Licence" : {
"localizations" : {
"ja" : {
Expand Down
16 changes: 16 additions & 0 deletions harmonie/Previews/AppViewModel+PreviewInitializer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// AppViewModel+PreviewInitializer.swift
// Harmonie
//
// Created by makinosp on 2024/10/20.
//

extension AppViewModel {
/// Initialize as preview mode
/// - Parameter isPreviewMode
convenience init(isPreviewMode: Bool) {
self.init()
services = APIServiceUtil(isPreviewMode: true, client: client)
user = PreviewDataProvider.shared.previewUser
}
}
6 changes: 3 additions & 3 deletions harmonie/Previews/PreviewContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import SwiftUI
import VRCKit

@MainActor
struct PreviewContainer<Content> where Content: View {
struct PreviewContainer<Content> {
private let content: Content
private let appVM: AppViewModel
private let friendVM: FriendViewModel
private let favoriteVM: FavoriteViewModel
}

extension PreviewContainer: View {
extension PreviewContainer: View where Content: View {
var body: some View {
content
.environment(appVM)
Expand All @@ -36,7 +36,7 @@ extension PreviewContainer: View {
}
}

extension PreviewContainer {
extension PreviewContainer where Content: View {
init(@ViewBuilder content: () -> Content) {
self.content = content()
appVM = AppViewModel(isPreviewMode: true)
Expand Down
2 changes: 1 addition & 1 deletion harmonie/Utils/DateUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

actor DateUtil: Sendable {
actor DateUtil {
static let shared = DateUtil()
private let relativeDateTimeFormatter: RelativeDateTimeFormatter
private let comparedComponents: Set<Calendar.Component>
Expand Down
2 changes: 1 addition & 1 deletion harmonie/Utils/KeychainUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import VRCKit

actor KeychainUtil: Sendable {
actor KeychainUtil {
static let shared = KeychainUtil()
private init() {}

Expand Down
2 changes: 1 addition & 1 deletion harmonie/Utils/ServiceUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import VRCKit

actor APIServiceUtil: Sendable {
actor APIServiceUtil {
let authenticationService: AuthenticationServiceProtocol
let favoriteService: FavoriteServiceProtocol
let friendService: FriendServiceProtocol
Expand Down
10 changes: 5 additions & 5 deletions harmonie/Utils/WindowUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@

import UIKit

@MainActor enum WindowUtil {
static var window: UIWindowScene? {
enum WindowUtil {
@MainActor static var window: UIWindowScene? {
UIApplication.shared.connectedScenes.first as? UIWindowScene
}

static var bounds: CGRect {
@MainActor static var bounds: CGRect {
window?.screen.bounds ?? .zero
}

static var height: CGFloat {
@MainActor static var height: CGFloat {
window?.screen.bounds.height ?? .zero
}

static var width: CGFloat {
@MainActor static var width: CGFloat {
window?.screen.bounds.width ?? .zero
}
}
21 changes: 3 additions & 18 deletions harmonie/ViewModels/AppViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ final class AppViewModel {
var isPresentedAlert = false
var vrckError: VRCKitError?
var isLoggingIn = false
var isRequiredReAuthentication = false
var services: APIServiceUtil
var verifyType: VerifyType?
@ObservationIgnored var client: APIClient
Expand Down Expand Up @@ -123,28 +122,14 @@ final class AppViewModel {

func handleError(_ error: Error) {
if let error = error as? VRCKitError {
if error == .unauthorized, step != .loggingIn {
isRequiredReAuthentication = true
guard error != .unauthorized else {
step = .loggingIn
return
}
vrckError = error
} else if !isCancelled(error) {
} else if !error.isCancelled {
vrckError = .unexpected
}
isPresentedAlert = vrckError != nil
}

private func isCancelled(_ error: Error) -> Bool {
(error as NSError?)?.isCancelled ?? false
}
}

extension AppViewModel {
/// Initialize as preview mode
/// - Parameter isPreviewMode
convenience init(isPreviewMode: Bool) {
self.init()
services = APIServiceUtil(isPreviewMode: true, client: client)
user = PreviewDataProvider.shared.previewUser
}
}
47 changes: 27 additions & 20 deletions harmonie/Views/Authentication/LoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,45 @@ struct LoginView: View {
@State private var password = ""
@State private var isPresentedSecurityPopover = false
@State private var isPresentedSavingPasswordPopover = false
@State private var isInInitializing = true
private let titleFont = "Avenir Next"

var body: some View {
@Bindable var appVM = appVM
NavigationStack {
VStack(spacing: 32) {
title
VStack(spacing: 16) {
loginFields
keychainToggle
enterButton
if isInInitializing {
ProgressScreen()
} else {
VStack(spacing: 32) {
title
VStack(spacing: 16) {
loginFields
keychainToggle
enterButton
}
}
.frame(maxWidth: 560)
.padding(.horizontal, 32)
.navigationDestination(item: $appVM.verifyType) { _ in
OtpView()
.navigationBarBackButtonHidden()
}
}
.frame(maxWidth: 560)
.padding(.horizontal, 32)
.navigationDestination(item: $appVM.verifyType) { _ in
OtpView()
.navigationBarBackButtonHidden()
}
}
.ignoresSafeArea(.keyboard)
.task {
guard isSavedOnKeyChain else { return }
if let password = await KeychainUtil.shared.getPassword(for: username) {
self.password = password
}
defer { isInInitializing = false }
guard isSavedOnKeyChain, !username.isEmpty else { return }
guard let password = await KeychainUtil.shared.getPassword(for: username) else { return }
self.password = password
await appVM.login(credential: cledential, isSavedOnKeyChain: isSavedOnKeyChain)
}
}

private var cledential: Credential {
Credential(username: username, password: password)
}

private var title: some View {
HStack(alignment: .lastTextBaseline) {
Text(verbatim: BundleUtil.appName.capitalized)
Expand Down Expand Up @@ -111,10 +121,7 @@ struct LoginView: View {

private var enterButton: some View {
AsyncButton {
await appVM.login(
credential: Credential(username: username, password: password),
isSavedOnKeyChain: isSavedOnKeyChain
)
await appVM.login(credential: cledential, isSavedOnKeyChain: isSavedOnKeyChain)
} label: {
if appVM.isLoggingIn {
ProgressView()
Expand Down
5 changes: 0 additions & 5 deletions harmonie/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ struct ContentView: View {
MainTabView()
.environment(FriendViewModel(appVM: appVM))
.environment(FavoriteViewModel())
.onChange(of: appVM.isRequiredReAuthentication) {
if appVM.isRequiredReAuthentication {
appVM.step = .loggingIn
}
}
.errorAlert()
}
}
Expand Down
Loading

0 comments on commit cd6b883

Please sign in to comment.