[Experimental Feature] Toast Notifications (#244)
commit c340cf842fbf5fea476a6637efe4928dbd734eba
Author: Chris Rittenhouse <dev@litritt.com>
Date: Thu Apr 27 17:24:30 2023 -0400
Addresses Riley's requested changes
- Minor code structure change in extension
- Minor changes to text and phrasing
commit 2a928dfa637dfb503e861dc863f6f85f5240941a
Author: Chris Rittenhouse <dev@litritt.com>
Date: Wed Apr 26 20:11:38 2023 -0400
Adds implementation for Toast Notifications Experimental Feature
commit 4fa7d139669994eff888c41bf7af9ac0b6cd2a75
Author: Chris Rittenhouse <dev@litritt.com>
Date: Wed Apr 26 20:11:04 2023 -0400
Adds @Feature and @Options for Toast Notifications Experimental Feature
Co-authored-by: Chris Rittenhouse <dev@litritt.com>
This commit is contained in:
parent
6bdc05f640
commit
7fceccc114
@ -34,6 +34,8 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1FA4ABA79AB72914FE414A61 /* libPods-Delta.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC866E433B3BA9AE18ABA1EC /* libPods-Delta.a */; };
|
1FA4ABA79AB72914FE414A61 /* libPods-Delta.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC866E433B3BA9AE18ABA1EC /* libPods-Delta.a */; };
|
||||||
87343D7B985519A5890A61C6 /* libPods-DeltaPreviews.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E3E5A45AB20C8A87754453B /* libPods-DeltaPreviews.a */; };
|
87343D7B985519A5890A61C6 /* libPods-DeltaPreviews.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E3E5A45AB20C8A87754453B /* libPods-DeltaPreviews.a */; };
|
||||||
|
AC1C991029F8B8C30020E6E4 /* ToastNotificationOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1C990F29F8B8C30020E6E4 /* ToastNotificationOptions.swift */; };
|
||||||
|
AC1C992729F9F1CF0020E6E4 /* GameViewController+ExperimentalToasts.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1C992629F9F1CF0020E6E4 /* GameViewController+ExperimentalToasts.swift */; };
|
||||||
ACF7E30D29F73D03000FE071 /* GameScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */; };
|
ACF7E30D29F73D03000FE071 /* GameScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */; };
|
||||||
ACF7E30F29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */; };
|
ACF7E30F29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */; };
|
||||||
BF00BEA625B758AA00C8607D /* SystemBIOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF00BEA525B758AA00C8607D /* SystemBIOS.swift */; };
|
BF00BEA625B758AA00C8607D /* SystemBIOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF00BEA525B758AA00C8607D /* SystemBIOS.swift */; };
|
||||||
@ -259,6 +261,8 @@
|
|||||||
8ECE6641DE30D01EA30FE7F6 /* Pods-DeltaPreviews.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeltaPreviews.release.xcconfig"; path = "Pods/Target Support Files/Pods-DeltaPreviews/Pods-DeltaPreviews.release.xcconfig"; sourceTree = "<group>"; };
|
8ECE6641DE30D01EA30FE7F6 /* Pods-DeltaPreviews.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeltaPreviews.release.xcconfig"; path = "Pods/Target Support Files/Pods-DeltaPreviews/Pods-DeltaPreviews.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
A01281C7023C0041B25963BE /* Pods-DeltaPreviews.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeltaPreviews.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DeltaPreviews/Pods-DeltaPreviews.debug.xcconfig"; sourceTree = "<group>"; };
|
A01281C7023C0041B25963BE /* Pods-DeltaPreviews.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeltaPreviews.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DeltaPreviews/Pods-DeltaPreviews.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
A19FF50F55441BC2B2248241 /* Pods-Delta.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Delta.release.xcconfig"; path = "Pods/Target Support Files/Pods-Delta/Pods-Delta.release.xcconfig"; sourceTree = "<group>"; };
|
A19FF50F55441BC2B2248241 /* Pods-Delta.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Delta.release.xcconfig"; path = "Pods/Target Support Files/Pods-Delta/Pods-Delta.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
AC1C990F29F8B8C30020E6E4 /* ToastNotificationOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastNotificationOptions.swift; sourceTree = "<group>"; };
|
||||||
|
AC1C992629F9F1CF0020E6E4 /* GameViewController+ExperimentalToasts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GameViewController+ExperimentalToasts.swift"; sourceTree = "<group>"; };
|
||||||
ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScreenshots.swift; sourceTree = "<group>"; };
|
ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScreenshots.swift; sourceTree = "<group>"; };
|
||||||
ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PHPhotoLibrary+Authorization.swift"; sourceTree = "<group>"; };
|
ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PHPhotoLibrary+Authorization.swift"; sourceTree = "<group>"; };
|
||||||
BF00BEA525B758AA00C8607D /* SystemBIOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemBIOS.swift; sourceTree = "<group>"; };
|
BF00BEA525B758AA00C8607D /* SystemBIOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemBIOS.swift; sourceTree = "<group>"; };
|
||||||
@ -531,6 +535,7 @@
|
|||||||
D524F4A4273DEBB400D500B2 /* ServerManager+Delta.swift */,
|
D524F4A4273DEBB400D500B2 /* ServerManager+Delta.swift */,
|
||||||
D5011C47281B6E8B00A0760B /* CharacterSet+Filename.swift */,
|
D5011C47281B6E8B00A0760B /* CharacterSet+Filename.swift */,
|
||||||
ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */,
|
ACF7E30E29F743A3000FE071 /* PHPhotoLibrary+Authorization.swift */,
|
||||||
|
AC1C992629F9F1CF0020E6E4 /* GameViewController+ExperimentalToasts.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1074,6 +1079,7 @@
|
|||||||
children = (
|
children = (
|
||||||
D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */,
|
D5A9C01C29DE058C00A8D610 /* VariableFastForward.swift */,
|
||||||
ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */,
|
ACF7E30C29F73D03000FE071 /* GameScreenshots.swift */,
|
||||||
|
AC1C990F29F8B8C30020E6E4 /* ToastNotificationOptions.swift */,
|
||||||
);
|
);
|
||||||
path = Features;
|
path = Features;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1490,6 +1496,7 @@
|
|||||||
BFBAB2E31EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift in Sources */,
|
BFBAB2E31EB685A2004E0B0E /* DeltaCoreProtocol+Delta.swift in Sources */,
|
||||||
BF3540081C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */,
|
BF3540081C5DAFAD00C1184C /* PauseTransitionCoordinator.swift in Sources */,
|
||||||
BF525EEA1FF6CD12004AA849 /* DeepLink.swift in Sources */,
|
BF525EEA1FF6CD12004AA849 /* DeepLink.swift in Sources */,
|
||||||
|
AC1C991029F8B8C30020E6E4 /* ToastNotificationOptions.swift in Sources */,
|
||||||
BF8A334621A4926F00A42FD4 /* GameSyncStatusViewController.swift in Sources */,
|
BF8A334621A4926F00A42FD4 /* GameSyncStatusViewController.swift in Sources */,
|
||||||
BF59427E1E09BC830051894B /* Game.swift in Sources */,
|
BF59427E1E09BC830051894B /* Game.swift in Sources */,
|
||||||
D5011C48281B6E8B00A0760B /* CharacterSet+Filename.swift in Sources */,
|
D5011C48281B6E8B00A0760B /* CharacterSet+Filename.swift in Sources */,
|
||||||
@ -1567,6 +1574,7 @@
|
|||||||
BF5942641E09BBB10051894B /* LoadControllerSkinImageOperation.swift in Sources */,
|
BF5942641E09BBB10051894B /* LoadControllerSkinImageOperation.swift in Sources */,
|
||||||
D5A98CE2284EF14B00E023E5 /* SceneDelegate.swift in Sources */,
|
D5A98CE2284EF14B00E023E5 /* SceneDelegate.swift in Sources */,
|
||||||
BFE56E1923EB7BE00014FECD /* UIImage+SymbolFallback.swift in Sources */,
|
BFE56E1923EB7BE00014FECD /* UIImage+SymbolFallback.swift in Sources */,
|
||||||
|
AC1C992729F9F1CF0020E6E4 /* GameViewController+ExperimentalToasts.swift in Sources */,
|
||||||
BF6EE5E91F7C5F860051AD6C /* _GameControllerInputMapping.swift in Sources */,
|
BF6EE5E91F7C5F860051AD6C /* _GameControllerInputMapping.swift in Sources */,
|
||||||
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
|
BF5942871E09BC8B0051894B /* _ControllerSkin.swift in Sources */,
|
||||||
BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */,
|
BF95E2791E4982A10030E7AD /* GamesDatabaseBrowserViewController.swift in Sources */,
|
||||||
|
|||||||
@ -726,6 +726,11 @@ private extension GameViewController
|
|||||||
|
|
||||||
try context.save()
|
try context.save()
|
||||||
try game.gameSaveURL.setExtendedAttribute(name: "com.rileytestut.delta.sha1Hash", value: hash)
|
try game.gameSaveURL.setExtendedAttribute(name: "com.rileytestut.delta.sha1Hash", value: hash)
|
||||||
|
|
||||||
|
if ExperimentalFeatures.shared.toastNotifications.gameSaveEnabled
|
||||||
|
{
|
||||||
|
self.presentExperimentalToastView(NSLocalizedString("Game Data Saved", comment: ""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch CocoaError.fileNoSuchFile
|
catch CocoaError.fileNoSuchFile
|
||||||
{
|
{
|
||||||
@ -844,6 +849,12 @@ extension GameViewController: SaveStatesViewControllerDelegate
|
|||||||
saveState.modifiedDate = Date()
|
saveState.modifiedDate = Date()
|
||||||
saveState.coreIdentifier = self.emulatorCore?.deltaCore.identifier
|
saveState.coreIdentifier = self.emulatorCore?.deltaCore.identifier
|
||||||
|
|
||||||
|
if ExperimentalFeatures.shared.toastNotifications.stateSaveEnabled,
|
||||||
|
saveState.type != .auto
|
||||||
|
{
|
||||||
|
self.presentExperimentalToastView(NSLocalizedString("Saved Save State", comment: ""))
|
||||||
|
}
|
||||||
|
|
||||||
if isRunning
|
if isRunning
|
||||||
{
|
{
|
||||||
self.resumeEmulation()
|
self.resumeEmulation()
|
||||||
@ -891,6 +902,11 @@ extension GameViewController: SaveStatesViewControllerDelegate
|
|||||||
{
|
{
|
||||||
try self.emulatorCore?.load(saveState)
|
try self.emulatorCore?.load(saveState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ExperimentalFeatures.shared.toastNotifications.stateLoadEnabled
|
||||||
|
{
|
||||||
|
self.presentExperimentalToastView(NSLocalizedString("Loaded Save State", comment: ""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch EmulatorCore.SaveStateError.doesNotExist
|
catch EmulatorCore.SaveStateError.doesNotExist
|
||||||
{
|
{
|
||||||
@ -1076,10 +1092,20 @@ extension GameViewController
|
|||||||
if activate
|
if activate
|
||||||
{
|
{
|
||||||
emulatorCore.rate = emulatorCore.deltaCore.supportedRates.upperBound
|
emulatorCore.rate = emulatorCore.deltaCore.supportedRates.upperBound
|
||||||
|
|
||||||
|
if ExperimentalFeatures.shared.toastNotifications.fastForwardEnabled
|
||||||
|
{
|
||||||
|
self.presentExperimentalToastView(NSLocalizedString("Fast Forward Enabled", comment: ""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emulatorCore.rate = emulatorCore.deltaCore.supportedRates.lowerBound
|
emulatorCore.rate = emulatorCore.deltaCore.supportedRates.lowerBound
|
||||||
|
|
||||||
|
if ExperimentalFeatures.shared.toastNotifications.fastForwardEnabled
|
||||||
|
{
|
||||||
|
self.presentExperimentalToastView(NSLocalizedString("Fast Forward Disabled", comment: ""))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,11 @@ struct ExperimentalFeatures: FeatureContainer
|
|||||||
options: GameScreenshotsOptions())
|
options: GameScreenshotsOptions())
|
||||||
var gameScreenshots
|
var gameScreenshots
|
||||||
|
|
||||||
|
@Feature(name: "Toast Notifications",
|
||||||
|
description: "Show toast notifications as a confirmation for various actions, such as saving your game or loading a save state.",
|
||||||
|
options: ToastNotificationOptions())
|
||||||
|
var toastNotifications
|
||||||
|
|
||||||
private init()
|
private init()
|
||||||
{
|
{
|
||||||
self.prepareFeatures()
|
self.prepareFeatures()
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// ToastNotificationOptions.swift
|
||||||
|
// Delta
|
||||||
|
//
|
||||||
|
// Created by Chris Rittenhouse on 4/25/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
import DeltaFeatures
|
||||||
|
|
||||||
|
struct ToastNotificationOptions
|
||||||
|
{
|
||||||
|
@Option(name: "Duration", description: "Change how long toasts should be shown.", detailView: { duration in
|
||||||
|
HStack {
|
||||||
|
Text("Duration: \(duration.wrappedValue, specifier: "%.1f")s")
|
||||||
|
Slider(value: duration, in: 1...5, step: 0.5).displayInline()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
var duration: Double = 1.5
|
||||||
|
|
||||||
|
@Option(name: "Game Data Saved",
|
||||||
|
description: "Show toasts when performing an in game save.")
|
||||||
|
var gameSaveEnabled: Bool = true
|
||||||
|
|
||||||
|
@Option(name: "Saved Save State",
|
||||||
|
description: "Show toasts when saving a save state.")
|
||||||
|
var stateSaveEnabled: Bool = true
|
||||||
|
|
||||||
|
@Option(name: "Loaded Save State",
|
||||||
|
description: "Show toasts when loading a save state.")
|
||||||
|
var stateLoadEnabled: Bool = true
|
||||||
|
|
||||||
|
@Option(name: "Fast Forward Toggled",
|
||||||
|
description: "Show toasts when toggling fast forward.")
|
||||||
|
var fastForwardEnabled: Bool = true
|
||||||
|
}
|
||||||
25
Delta/Extensions/GameViewController+ExperimentalToasts.swift
Normal file
25
Delta/Extensions/GameViewController+ExperimentalToasts.swift
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// GameViewController+ExperimentalToasts.swift
|
||||||
|
// Delta
|
||||||
|
//
|
||||||
|
// Created by Chris Rittenhouse on 4/26/23.
|
||||||
|
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Roxas
|
||||||
|
|
||||||
|
extension GameViewController
|
||||||
|
{
|
||||||
|
func presentExperimentalToastView(_ text: String)
|
||||||
|
{
|
||||||
|
guard ExperimentalFeatures.shared.toastNotifications.isEnabled else { return }
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let toastView = RSTToastView(text: text, detailText: nil)
|
||||||
|
toastView.edgeOffset.vertical = 8
|
||||||
|
toastView.textLabel.textAlignment = .center
|
||||||
|
toastView.presentationEdge = .top
|
||||||
|
toastView.show(in: self.view, duration: ExperimentalFeatures.shared.toastNotifications.duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user