Skip to content

Commit

Permalink
Improves FavoriteButton implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mntone committed Jan 4, 2024
1 parent 6549564 commit 8e03e53
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/App/ViewModels/GameItemViewModel.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import MonsterAnalyzerCore

final class GameItemViewModel: ObservableObject, Identifiable, FavoriteViewModel {
final class GameItemViewModel: ObservableObject, Identifiable {
private let monster: Monster

@Published
Expand Down
2 changes: 1 addition & 1 deletion src/App/ViewModels/MonsterViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Combine
import Foundation
import MonsterAnalyzerCore

final class MonsterViewModel: ObservableObject, Identifiable, FavoriteViewModel {
final class MonsterViewModel: ObservableObject, Identifiable {
private let monster: Monster
#if !os(watchOS)
private let notifier: DebounceNotifier<String>
Expand Down
5 changes: 0 additions & 5 deletions src/App/ViewModels/Protocols/FavoriteViewModel.swift

This file was deleted.

17 changes: 6 additions & 11 deletions src/App/Views/Details/FavoriteButton.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import SwiftUI

struct FavoriteButton<ViewModel: FavoriteViewModel>: View {
@ObservedObject
private(set) var viewModel: ViewModel
struct FavoriteButton: View {
@Binding
private(set) var favorite: Bool

var body: some View {
let text: LocalizedStringKey, image: String
if viewModel.isFavorited {
if favorite {
text = "Remove Favorite"
image = "star.fill"
} else {
Expand All @@ -15,14 +15,9 @@ struct FavoriteButton<ViewModel: FavoriteViewModel>: View {
}

return Button(text, systemImage: image) {
#if os(watchOS)
viewModel.isFavorited.toggle()
#else
withAnimation {
viewModel.isFavorited.toggle()
}
#endif
favorite.toggle()
}
.animation(.easeInOut, value: favorite)
#if os(watchOS)
.foregroundStyle(.yellow)
#else
Expand Down
2 changes: 1 addition & 1 deletion src/App/Views/Details/MonsterView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct MonsterView: View {
}
#endif
.toolbarItemBackport(alignment: .trailing) {
FavoriteButton(viewModel: viewModel)
FavoriteButton(favorite: $viewModel.isFavorited)
}
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
Expand Down
24 changes: 8 additions & 16 deletions src/App/Views/FavoriteContextMenuButton.swift
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
import SwiftUI

@available(watchOS, unavailable)
struct FavoriteContextMenuButton<ViewModel: FavoriteViewModel>: View {
@ObservedObject
private(set) var viewModel: ViewModel
struct FavoriteContextMenuButton: View {
@Binding
private(set) var favorite: Bool

var body: some View {
let text: LocalizedStringKey, image: String
if viewModel.isFavorited {
if favorite {
text = "Remove Favorite"
image = "star.fill"
image = "star.slash"
} else {
text = "Add to Favorites"
image = "star"
}

return Button(text, systemImage: image) {
viewModel.isFavorited.toggle()
favorite.toggle()
}
}
}

final class _PreviewFavoriteViewModel: FavoriteViewModel {
var isFavorited: Bool

init(isFavorited: Bool) {
self.isFavorited = isFavorited
}
}

#Preview("Favorite") {
Text(verbatim: "Sample Context Menu")
.padding()
.contextMenu {
FavoriteContextMenuButton(viewModel: _PreviewFavoriteViewModel(isFavorited: false))
FavoriteContextMenuButton(favorite: .constant(false))
}
}

#Preview("Unfavorite") {
Text(verbatim: "Sample Context Menu")
.padding()
.contextMenu {
FavoriteContextMenuButton(viewModel: _PreviewFavoriteViewModel(isFavorited: true))
FavoriteContextMenuButton(favorite: .constant(true))
}
}
5 changes: 3 additions & 2 deletions src/App/Views/MonsterListItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ struct MonsterListItem: View {
Image(systemName: "star.fill")
.foregroundStyle(.yellow)
.accessibilityLabel("Favorited")
.transition(.opacity.animation(.easeInOut(duration: 0.1)))
.transition(.opacity)
}
}
.animation(.easeInOut(duration: 0.1), value: viewModel.isFavorited)
#if !os(watchOS)
.contextMenu {
FavoriteContextMenuButton(viewModel: viewModel)
FavoriteContextMenuButton(favorite: $viewModel.isFavorited)
}
#endif
}
Expand Down
6 changes: 0 additions & 6 deletions src/MonsterAnalyzer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,6 @@
EBF9282F2B1038CB007D59D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EBF9282E2B1038CB007D59D4 /* Assets.xcassets */; };
EBF928332B1038CB007D59D4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EBF928322B1038CB007D59D4 /* Preview Assets.xcassets */; };
EBFEAB842B45A5DC005363F7 /* FavoriteContextMenuButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFEAB832B45A5DC005363F7 /* FavoriteContextMenuButton.swift */; };
EBFEAB872B45A805005363F7 /* FavoriteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFEAB862B45A805005363F7 /* FavoriteViewModel.swift */; };
EBFEAB882B45A805005363F7 /* FavoriteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFEAB862B45A805005363F7 /* FavoriteViewModel.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -485,7 +483,6 @@
EBF928302B1038CB007D59D4 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = "<group>"; };
EBF928322B1038CB007D59D4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
EBFEAB832B45A5DC005363F7 /* FavoriteContextMenuButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteContextMenuButton.swift; sourceTree = "<group>"; };
EBFEAB862B45A805005363F7 /* FavoriteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteViewModel.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -1025,7 +1022,6 @@
EBFEAB852B45A7F7005363F7 /* Protocols */ = {
isa = PBXGroup;
children = (
EBFEAB862B45A805005363F7 /* FavoriteViewModel.swift */,
);
path = Protocols;
sourceTree = "<group>";
Expand Down Expand Up @@ -1270,7 +1266,6 @@
EBB4B20E2B175DE2004D63EA /* Effective.swift in Sources */,
EB8778292B26BDEF00B3359C /* EnvironmentValues+PresentSettingsSheetAction.swift in Sources */,
EB560BCF2B42F48800E91E01 /* FavoriteButton.swift in Sources */,
EBFEAB882B45A805005363F7 /* FavoriteViewModel.swift in Sources */,
EBB4B21C2B176CE7004D63EA /* FixedWidthWeaknessView.swift in Sources */,
EBBBAABA2B3FE27000BBAB23 /* GameGroupViewModel.swift in Sources */,
EBBBAAB52B3FADEB00BBAB23 /* GameItemViewModel.swift in Sources */,
Expand Down Expand Up @@ -1421,7 +1416,6 @@
EB8778282B26BDEF00B3359C /* EnvironmentValues+PresentSettingsSheetAction.swift in Sources */,
EB560BCE2B42F48800E91E01 /* FavoriteButton.swift in Sources */,
EBFEAB842B45A5DC005363F7 /* FavoriteContextMenuButton.swift in Sources */,
EBFEAB872B45A805005363F7 /* FavoriteViewModel.swift in Sources */,
EBCA222E2B228C6800C487AD /* FixedWidthWeaknessView.swift in Sources */,
EBDFD8512B3C112A00AF1832 /* GameGroupViewModel.swift in Sources */,
EBBBAAB42B3FADEB00BBAB23 /* GameItemViewModel.swift in Sources */,
Expand Down

0 comments on commit 8e03e53

Please sign in to comment.