Skip to content

Commit

Permalink
0.2.1-alpha
Browse files Browse the repository at this point in the history
  • Loading branch information
vapidinfinity authored Jun 18, 2024
2 parents ef2c051 + c8f3977 commit 9a1ba6b
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 68 deletions.
4 changes: 2 additions & 2 deletions Mythic.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2754;
CURRENT_PROJECT_VERSION = 2780;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = 67ZBY275P8;
Expand Down Expand Up @@ -748,7 +748,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 2754;
CURRENT_PROJECT_VERSION = 2780;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_ASSET_PATHS = "\"Mythic/Preview Content\"";
DEVELOPMENT_TEAM = 67ZBY275P8;
Expand Down
74 changes: 48 additions & 26 deletions Mythic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
alert.addButton(withTitle: "Move")
alert.addButton(withTitle: "Cancel")

if case .alertFirstButtonReturn = alert.runModal(), let optimalAppURL = optimalAppURL {
if let window = NSApp.windows.first,
let optimalAppURL = optimalAppURL,
case .alertFirstButtonReturn = alert.beginSheetModal(for: window) {
do {
_ = try files.replaceItemAt(optimalAppURL, withItemAt: currentAppURL)
workspace.open(optimalAppURL)
Expand Down Expand Up @@ -124,29 +126,41 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
if Engine.needsUpdate() == true {
let alert = NSAlert()
alert.messageText = "Time for an update!"
alert.informativeText = "A new Mythic Engine update has been pushed."
alert.informativeText = "A new Mythic Engine update has released."
alert.addButton(withTitle: "Update")
alert.addButton(withTitle: "Cancel")

if case .alertFirstButtonReturn = alert.runModal() {
let confirmation = NSAlert()
confirmation.messageText = "Are you sure you want to update now?"
confirmation.informativeText = "Updating will remove the current version of Mythic Engine before installing the new one."
confirmation.addButton(withTitle: "Update")
confirmation.addButton(withTitle: "Cancel")

if case .alertFirstButtonReturn = confirmation.runModal() {
do {
try Engine.remove()
let app = MythicApp() // FIXME: is this dangerous or just stupid
app.onboardingPhase = .engineDisclaimer
app.isOnboardingPresented = true
} catch {
let error = NSAlert()
error.messageText = "Unable to remove Mythic Engine."
error.addButton(withTitle: "Quit")
if case .OK = error.runModal() {
exit(1)
alert.showsHelp = true

if let window = NSApp.windows.first { // no alternative ATM, swift compiler is clueless.
alert.beginSheetModal(for: window) { response in
if case .alertFirstButtonReturn = response {
let confirmation = NSAlert()
confirmation.messageText = "Are you sure you want to update now?"
confirmation.informativeText = "Updating will remove the current version of Mythic Engine before installing the new one."
confirmation.addButton(withTitle: "Update")
confirmation.addButton(withTitle: "Cancel")

confirmation.beginSheetModal(for: window) { response in
if case .alertFirstButtonReturn = response {
do {
try Engine.remove()
let app = MythicApp() // FIXME: is this dangerous or just stupid
app.onboardingPhase = .engineDisclaimer
app.isOnboardingPresented = true
} catch {
let error = NSAlert()
error.alertStyle = .critical
error.messageText = "Unable to remove Mythic Engine."
error.addButton(withTitle: "Quit")

error.beginSheetModal(for: window) { response in
if case .OK = response {
exit(1)
}
}
}
}
}
}
}
Expand All @@ -155,20 +169,28 @@ class AppDelegate: NSObject, NSApplicationDelegate { // https://arc.net/l/quote/
}

func applicationShouldTerminate(_: NSApplication) -> NSApplication.TerminateReply {
var terminateReply: NSApplication.TerminateReply = .terminateNow

if GameOperation.shared.current != nil || !GameOperation.shared.queue.isEmpty {
let alert = NSAlert()
alert.messageText = "Are you sure you want to quit?"
alert.informativeText = "Mythic is still modifying games."
alert.alertStyle = .warning
alert.addButton(withTitle: "Quit")
alert.addButton(withTitle: "Cancel")
if alert.runModal() == .alertFirstButtonReturn {
return .terminateNow
} else {
return .terminateCancel

if let window = NSApp.windows.first {
alert.beginSheetModal(for: window) { response in
if case .alertFirstButtonReturn = response {
terminateReply = .terminateNow
} else {
terminateReply = .terminateLater
}
}
}
}

return .terminateNow
return terminateReply
}

func applicationWillTerminate(_: Notification) {
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -39245,4 +39245,4 @@
}
},
"version" : "1.0"
}
}
33 changes: 20 additions & 13 deletions Mythic/Utilities/Game.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Combine
import OSLog
import UserNotifications
import SwordRPC
import SwiftUI

/// Enumeration containing the two different game platforms available.
enum GamePlatform: String, CaseIterable, Codable, Hashable {
Expand Down Expand Up @@ -89,10 +90,15 @@ class Game: ObservableObject, Hashable, Codable, Identifiable, Equatable {
var bottleURL: URL? {
get {
let key: String = id.appending("_bottleURL")
if !Wine.bottleURLs.isEmpty {
defaults.register(defaults: [key: Wine.bottleURLs.first!])
if let url = defaults.url(forKey: key), !Wine.bottleExists(bottleURL: url) {
defaults.removeObject(forKey: key)
}
return defaults.url(forKey: key) ?? Wine.bottleURLs.first

if defaults.url(forKey: key) == nil {
defaults.set(Wine.bottleURLs.first, forKey: key)
}

return defaults.url(forKey: key)
}
set {
let key: String = id.appending("_bottleURL")
Expand Down Expand Up @@ -211,16 +217,17 @@ class GameOperation: ObservableObject {
trigger: nil)
)
} catch {
try await notifications.add(
.init(identifier: UUID().uuidString,
content: {
let content = UNMutableNotificationContent()
content.title = "Error \(GameOperation.shared.current?.type.rawValue ?? "modifying") \"\(GameOperation.shared.current?.game.title ?? "Unknown")\"."
content.body = error.localizedDescription
return content
}(),
trigger: nil)
)
DispatchQueue.main.async {
let alert = NSAlert()
alert.messageText = "Error \(GameOperation.shared.current?.type.rawValue ?? "modifying") \"\(GameOperation.shared.current?.game.title ?? "Unknown")\"."
alert.informativeText = error.localizedDescription
alert.alertStyle = .warning
alert.addButton(withTitle: "OK")

if let window = NSApp.windows.first {
alert.beginSheetModal(for: window)
}
}
}

DispatchQueue.main.asyncAndWait {
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Utilities/Legendary/LegendaryInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ final class Legendary {
*/
static func launch(game: Mythic.Game, online: Bool) async throws {
guard try Legendary.getInstalledGames().contains(game) else {
log.error("Unable to launch game, not installed or missing") // TODO: add alert in unified alert system
log.error("Unable to launch game, not installed or missing")
throw GameDoesNotExistError(game)
}

Expand Down
2 changes: 1 addition & 1 deletion Mythic/Utilities/Local/LocalGames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class LocalGames {

guard let library = library,
library.contains(game) else {
log.error("Unable to launch local game, not installed or missing") // TODO: add alert in unified alert system
log.error("Unable to launch local game, not installed or missing")
throw GameDoesNotExistError(game)
}

Expand Down
2 changes: 2 additions & 0 deletions Mythic/Views/Navigation/DownloadsEvo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ struct DownloadsEvo: View {
if let currentGame = operation.current?.game {
VStack {
DownloadCard(game: currentGame, style: .prominent)

Divider()

if operation.queue.isEmpty {
Text("No other downloads are pending.")
.bold()
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Views/Navigation/Home.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct HomeView: View {
if !unifiedGames.filter({ $0.isFavourited == true }).isEmpty {
ScrollView(.horizontal) {
LazyHGrid(rows: [.init(.adaptive(minimum: 115))]) {
ForEach(unifiedGames.filter({ $0.isFavourited == true }), id: \.self) { game in
ForEach(unifiedGames.filter({ $0.isFavourited == true })) { game in
CompactGameCard(game: .constant(game))
.padding(5)
}
Expand Down
7 changes: 1 addition & 6 deletions Mythic/Views/Navigation/Library/Library.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ struct LibraryView: View {

// MARK: - State Variables
@State private var isGameImportSheetPresented = false
@State private var legendaryStatus: JSON = JSON()
@State private var isDownloadsPopoverPresented: Bool = false

@State private var searchText: String = .init()

// MARK: - Body
var body: some View {
// GameListView(isRefreshCalled: $isGameListRefreshCalled, searchText: $searchText)
GameListEvo()
.navigationTitle("Library")

Expand All @@ -49,7 +44,7 @@ struct LibraryView: View {

// MARK: Refresh Button
Button {
_ = unifiedGames // getter updates computer property

} label: {
Image(systemName: "arrow.clockwise")
}
Expand Down
2 changes: 1 addition & 1 deletion Mythic/Views/Unified/BottleListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ struct BottleConfigurationView: View {
Button("Launch Registry Editor") {
Task { try await Wine.command(arguments: ["regedit"], identifier: "regedit", bottleURL: bottle.url) { _ in } }
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
registryEditorActive = (try? Process.execute("/bin/bash", arguments: ["-c", "ps aux | grep regedit.exe | grep -v grep"]))?.isEmpty == false // @isaacmarovitz has a better way
registryEditorActive = (try? Process.execute("/bin/bash", arguments: ["-c", "ps aux | grep regedit.exe | grep -v grep"]))?.isEmpty == false // TODO: tasklist
if !registryEditorActive { timer.invalidate() }
}
}
Expand Down
17 changes: 15 additions & 2 deletions Mythic/Views/Unified/GameListEvoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,21 @@ struct GameListEvo: View {
searchString.isEmpty ||
$0.title.localizedCaseInsensitiveContains(searchString)
}
.sorted(by: { $0.title < $1.title })
.sorted(by: { $0.isFavourited && !$1.isFavourited })
.sorted {
if $0.isFavourited != $1.isFavourited {
return $0.isFavourited && !$1.isFavourited
}

if let games = try? Legendary.getInstalledGames(), games.contains($0) != games.contains($1) {
return games.contains($0)
}

if let games = LocalGames.library, games.contains($0) != games.contains($1) {
return games.contains($0)
}

return $0.title < $1.title
}
}

var body: some View {
Expand Down
15 changes: 1 addition & 14 deletions Mythic/Views/Unified/Models/GameCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct GameCard: View {
HStack {
Text(game.title)
.font(.bold(.title3)())
// .foregroundStyle(.white)
.foregroundStyle(.white)

SubscriptedTextView(game.type.rawValue)

Expand Down Expand Up @@ -132,19 +132,6 @@ struct GameCard: View {
game: game, platform: game.platform!, type: .repair
)
)

/*
do {
try await Legendary.install(
game: game,
platform: game.platform!,
type: .repair
)
} catch {
Logger.app.error("Error repairing \(game.title): \(error.localizedDescription)")
// TODO: add repair error
}
*/
}
} label: {
Image(systemName: "checkmark.circle.badge.questionmark")
Expand Down
14 changes: 14 additions & 0 deletions Mythic/Views/Unified/Sheets/InstallGameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct InstallViewEvo: View {
@State var selectedOptionalPacks: Set<String> = .init()
@State var fetchingOptionalPacks: Bool = true

@State var installSize: Double?

@State private var supportedPlatforms: [GamePlatform]?
@State var platform: GamePlatform = .macOS

Expand Down Expand Up @@ -43,6 +45,12 @@ struct InstallViewEvo: View {
}
}
}

if output.stderr.contains("Install size:") {
if let match = try? Regex(#"Install size: (\d+(\.\d+)?) MiB"#).firstMatch(in: output.stderr) {
installSize = Double(match[1].substring ?? "") ?? 0.0
}
}
}

fetchingOptionalPacks = false
Expand Down Expand Up @@ -167,6 +175,12 @@ struct InstallViewEvo: View {
Spacer()

HStack {
if let installSize = installSize {
Text("\(String(format: "%.2f", Double(installSize * (1000000 / 1048576)) / (installSize > 1024 ? 1024 : 1))) \(installSize > 1024 ? "GB" : "MB")")
.font(.footnote)
.foregroundStyle(.placeholder)
}

if fetchingOptionalPacks {
ProgressView()
.controlSize(.small)
Expand Down

0 comments on commit 9a1ba6b

Please sign in to comment.