Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ETA to Wine Download #161

Merged
merged 6 commits into from
Jun 25, 2023
Merged

Conversation

benwaco
Copy link
Contributor

@benwaco benwaco commented Jun 22, 2023

No description provided.

@benwaco
Copy link
Contributor Author

benwaco commented Jun 22, 2023

Screenshot 2023-06-22 at 12 01 14 PM

@benwaco benwaco changed the title Add ETA to Wine download Add ETA to Wine Download Jun 22, 2023
@benwaco benwaco changed the title Add ETA to Wine Download Add ETA to Wine Download & Improve some English Naming Jun 22, 2023
@benwaco benwaco changed the title Add ETA to Wine Download & Improve some English Naming Add ETA to Wine Download Jun 22, 2023
Copy link
Contributor

@JoshuaBrest JoshuaBrest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to edit all translation files and it would be nice if they were the eta was a separate string on the right.

Whisky/da.lproj/Localizable.strings Outdated Show resolved Hide resolved
Whisky/Views/Setup Views/WineDownloadView.swift Outdated Show resolved Hide resolved
Whisky/Views/Setup Views/WineDownloadView.swift Outdated Show resolved Hide resolved
Add "Progress: & ETA:" back to Wine Download View. Improve handling of Download ETA using optional protection.
@JoshuaBrest
Copy link
Contributor

I have updated the file, but, i don't have write access so I will have to ask you to do it.

//
//  WineDownloadView.swift
//  Whisky
//
//  Created by Isaac Marovitz on 20/06/2023.
//

import SwiftUI

struct WineDownloadView: View {
    @State private var fractionProgress: Double = 0
    @State private var completedBytes: Int64 = 0
    @State private var totalBytes: Int64 = 0
    @State private var downloadSpeed: Double = 0
    @State private var downloadTask: URLSessionDownloadTask?
    @State private var observation: NSKeyValueObservation?
    @State private var startTime: Date?
    @Binding var tarLocation: URL
    @Binding var path: [SetupStage]
    var body: some View {
        VStack {
            VStack {
                Text("setup.wine.download")
                    .font(.title)
                Text("setup.wine.download.subtitle")
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
                Spacer()
                VStack {
                    ProgressView(value: fractionProgress, total: 1)
                    HStack {
                        HStack {
                            Text(String(format: String(localized: "setup.wine.progress"),
                                        formatPercentage(fractionProgress),
                                        formatBytes(completed: completedBytes, total: totalBytes)))
                            Spacer()
                            Text(shouldShowEstimate()
                                 ? String(format: String(localized: "setup.wine.eta"),
                                         formatRemainingTime(remainingBytes: totalBytes - completedBytes))
                                 : String(localized: "setup.wine.estimating"))
                        }
                        .font(.subheadline)
                    }
                }
                .padding(.horizontal)
                Spacer()
            }
            Spacer()
        }
        .frame(width: 400, height: 200)
        .onAppear {
            Task {
                if let downloadInfo = await WineDownload.getLatestWineURL(),
                   let url = downloadInfo.directURL {
                    downloadTask = URLSession.shared.downloadTask(with: url) { url, _, _ in
                        if let url = url {
                            tarLocation = url
                            proceed()
                        }
                    }
                    observation = downloadTask?.observe(\.countOfBytesReceived) { task, _ in
                        Task {
                            await MainActor.run {
                                let currentTime = Date()
                                let elapsedTime = currentTime.timeIntervalSince(startTime ?? currentTime)
                                if completedBytes > 0 {
                                    downloadSpeed = Double(completedBytes) / elapsedTime
                                }
                                fractionProgress = Double(task.countOfBytesReceived) / Double(totalBytes)
                                completedBytes = task.countOfBytesReceived
                            }
                        }
                    }
                    startTime = Date()
                    downloadTask?.resume()
                    await MainActor.run {
                        totalBytes = Int64(downloadInfo.totalByteCount)
                    }
                }
            }
        }
    }
    func formatPercentage(_ value: Double) -> String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .percent
        formatter.maximumFractionDigits = 0
        formatter.minimumIntegerDigits = 1
        return formatter.string(from: value as NSNumber) ?? ""
    }
    func formatBytes(completed: Int64, total: Int64) -> String {
        let formatter = ByteCountFormatter()
        formatter.countStyle = .file
        let completed = formatter.string(fromByteCount: completed)
        let total = formatter.string(fromByteCount: total)
        return "(\(completed)/\(total))"
    }
    func shouldShowEstimate() -> Bool {
        let elapsedTime = Date().timeIntervalSince(startTime ?? Date())
        return Int(elapsedTime.rounded()) > 5 && completedBytes != 0
    }
    func formatRemainingTime(remainingBytes: Int64) -> String {
        let remainingTimeInSeconds = Double(remainingBytes) / downloadSpeed

        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.hour, .minute, .second]
        formatter.unitsStyle = .abbreviated
        return formatter.string(from: TimeInterval(remainingTimeInSeconds)) ?? ""
    }
    func proceed() {
        path.append(.wineInstall)
    }
}

@JoshuaBrest
Copy link
Contributor

localizables.strings

"tab.config" = "Config";
"tab.programs" = "Programs";
"tab.info" = "Info";

"tab.navTitle.config" = "%@ Config";
"tab.navTitle.programs" = "%@ Programs";
"tab.navTitle.info" = "%@ Info";

"button.cDrive" = "Open C Drive";
"button.showInFinder" = "Show in Finder";
"button.run" = "Run...";
"button.ok" = "OK";
"button.renameBottle" = "Rename";
"button.deleteBottle" = "Delete...";
"button.createBottle" = "Create Bottle";
"button.deleteAlert.msg" = "Delete %@?";
"button.deleteAlert.info" = "Are you sure you want to delete this bottle? This action is permanent.";
"button.deleteAlert.delete" = "Delete";
"button.deleteAlert.cancel" = "Cancel";

"config.winVersion" = "Windows Version";
"config.buildVersion" = "Build Version";
"config.title.metal" = "Metal";
"config.metalHud" = "Metal HUD";
"config.metalTrace" = "Metal Trace";
"config.retinaMode" = "Retina Mode";
"config.metalTrace.info" = "Allows you to capture GPU workload in Xcode";
"config.esync" = "ESync";
"config.controlPanel" = "Open Control Panel";
"config.regedit" = "Open Registry Editor";
"config.winecfg" = "Open Wine Configuration";

"program.title" = "Installed Programs";
"program.env" = "Environment Variables";
"program.args" = "Arguments";
"program.config" = "Config";

"info.title" = "Info";
"info.path" = "Path";
"info.path.copy" = "Copy Path";
"info.winPath.copy" = "Copy Windows Path";
"info.wine" = "Wine Version";
"info.win" = "Windows Version";

"gptkalert.init" = "Drag and drop the Game Porting Toolkit DMG";
"gptkalert.message" = "GPTK encountered an error!";

"alert.message" = "Failed to open program!";
"alert.info" = "Failed to open";

"create.title" = "Create a new bottle";
"create.name" = "Bottle name:";
"create.win" = "Windows version:";
"create.path" = "Bottle path:";
"create.browse" = "Browse";
"create.cancel" = "Cancel";
"create.create" = "Create";
"create.warning.emptyName" = "Name can't be empty";
"create.warning.alreadyExistsName" = "A bottle with this name already exists";

"rename.title" = "Rename bottle";
"rename.name" = "New name:";
"rename.rename" = "Rename";

"check.updates" = "Check for Updates...";
"kill.bottles" = "Kill All Bottles";
"open.logs" = "Open Logs Folder";

"showAlertOnFirstLaunch.messageText" = "Would you like to move Whisky to your Applications folder?";
"showAlertOnFirstLaunch.informativeText" = "In some cases, Whisky wont't be able to function properly from a different folder";
"showAlertOnFirstLaunch.button.moveToApplications" = "Move to Applications";
"showAlertOnFirstLaunch.button.dontMove" = "Don't Move";

"setup.welcome" = "Welcome to Whisky";
"setup.welcome.subtitle" = "Let's get you set up. This won't take a minute.";

"setup.install.checking" = "Checking %@ installation...";
"setup.install.installed" = "%@ installed";
"setup.install.notInstalled" = "%@ not installed";

"setup.rosetta" = "Installing Rosetta";
"setup.rosetta.subtitle" = "Rosetta allows x86 code, like Wine, to run on your Mac.";

"setup.wine.download" = "Downloading Wine";
"setup.wine.download.subtitle" = "Speeds will vary on your internet connection.";
"setup.wine.progress" = "Progress: %@ %@";
"setup.wine.eta" = "Time Remaining: %@";
"setup.wine.estimating" = "Estimating...";

"setup.wine.install" = "Installing Wine";
"setup.wine.install.subtitle" = "Almost there. Don't tune out yet.";

"setup.gptk" = "Installing GPTK";

@IsaacMarovitz
Copy link
Member

Screenshot 2023-06-24 at 23 44 03

Might be a good idea to make it match Apple's usual format

@JoshuaBrest
Copy link
Contributor

Screenshot 2023-06-24 at 23 44 03 Might be a good idea to make it match Apple's usual format

i don't think it has to be exact.

@IsaacMarovitz IsaacMarovitz merged commit 1efae01 into Whisky-App:main Jun 25, 2023
1 check passed
@benwaco benwaco deleted the wine-download-eta branch June 25, 2023 12:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants