Skip to content

Commit

Permalink
Merge pull request #161 from allenai/160-disclose-download-size
Browse files Browse the repository at this point in the history
Add download disclosure and confirmation
  • Loading branch information
Stanley-Jovel authored Feb 6, 2025
2 parents 1aab96f + f56d9da commit d6c1ce6
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 43 deletions.
1 change: 1 addition & 0 deletions OLMoE.swift/Constants/AppConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ enum AppConstants {
enum Model {
static let filename = "OLMoE-latest"
static let downloadURL = "https://dolma-artifacts.org/app/\(filename).gguf"
static let playgroundURL = "https://playground.allenai.org/?model=olmoe-0125"
}
}
6 changes: 6 additions & 0 deletions OLMoE.swift/Constants/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@
},
"Proceed With Mocked Model" : {

},
"Start Download" : {

},
"The model requires 4.21GB of storage space. Would you like to proceed with the download?" : {

},
"This device does not have the 8GB physical RAM required to run OLMoE locally." : {

Expand Down
27 changes: 8 additions & 19 deletions OLMoE.swift/Extensions/DeviceSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,19 @@
import SwiftUI
import os

func deviceHasEnoughRam() -> Bool {
let requiredRAM: UInt64 = 6 * 1024 * 1024 * 1024
let totalRAM = ProcessInfo.processInfo.physicalMemory
print("Total RAM (GB)", totalRAM / (1024 * 1024 * 1024))
return totalRAM >= requiredRAM
}

// Device support check function
func isDeviceSupported() -> Bool {
#if targetEnvironment(simulator)
return true
#else
let deviceModel = UIDevice.current.modelName

// Model identifiers for devices with 8GB of RAM or more (iPhones and iPads)
let supportedModels = [
// iPhone models with 8GB RAM
"iPhone16,1", "iPhone16,2", // iPhone 15 Pro and Pro Max
"iPhone17,1", "iPhone17,2", "iPhone17,3", "iPhone17,4", // all iPhone 16 models

// iPad models with 8GB or more RAM
"iPad14,3", "iPad14,4", // iPad Pro 11" 4th Gen
"iPad14,5", "iPad14,6", // iPad Pro 12.9" 6th Gen
"iPad16,3", "iPad16,4", // iPad Pro 11" 5th Gen
"iPad16,5", "iPad16,6", // iPad Pro 12.9" 7th Gen
"iPad13,16", "iPad13,17", // iPad Air 5th Gen
"iPad14,8", "iPad14,9", // iPad Air 6th Gen
"iPad15,1", "iPad15,2", // Hypothetical future iPad models with 8GB RAM
]

return supportedModels.contains(deviceModel)
return deviceHasEnoughRam()
#endif
}

Expand Down
69 changes: 48 additions & 21 deletions OLMoE.swift/Views/InfoPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,46 +16,73 @@ struct InfoButton: View {
Image(systemName: "info.circle")
.foregroundColor(Color("TextColor"))
}
.buttonStyle(.plain)
.clipShape(Circle())
.background(
RadialGradient(
gradient: Gradient(colors: [
Color("BackgroundColor").opacity(0.9), Color.clear,
]),
center: .center,
startRadius: 20,
endRadius: 40)
)
.background(Color.clear)
}
}

struct CloseButton: View {
let action: () -> Void

var body: some View {
Button(action: action) {
Image(systemName: "xmark.circle")
.font(.system(size: 20))
.frame(width: 40, height: 40)
.foregroundColor(Color("TextColor"))
}
.buttonStyle(.plain)
.clipShape(Circle())
}
}

struct InfoContent: View {
var body: some View {
VStack(alignment: .leading, spacing: 20) {
ForEach(InfoText.content) { text in
HeaderTextPairView(header: text.header, text: text.text)
.padding([.horizontal], 12)
}
}
.padding([.bottom], 24)
}
}

struct InfoView: View {
@Binding var isPresented: Bool

var body: some View {
#if targetEnvironment(macCatalyst)
VStack(spacing: 0) {
// Fixed header
HStack {
Spacer()
CloseButton(action: { isPresented = false })
}
.padding([.top, .horizontal], 12)

// Scrollable content
ScrollView {
InfoContent()
}
}
#else
ScrollView {
VStack(alignment: .leading, spacing: 20) {
HStack {
Spacer()
Button(action: { isPresented = false }) {
Image(systemName: "xmark.circle")
.font(.system(size: 20))
.frame(width: 40, height: 40)
.foregroundColor(Color("TextColor"))
}
.clipShape(Circle())
CloseButton(action: { isPresented = false })
}

ForEach(InfoText.content) { text in
HeaderTextPairView(header: text.header, text: text.text)
.padding([.horizontal], 12)
}
InfoContent()
}
.padding([.bottom], 24)
}
#endif
}
}

#Preview("InfoView") {
InfoView(isPresented: .constant(true))
}
}
39 changes: 37 additions & 2 deletions OLMoE.swift/Views/ModelDownloadView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ struct Ai2Logo: View {
/// A view that displays the model download progress and status.
struct ModelDownloadView: View {
@StateObject private var downloadManager = BackgroundDownloadManager.shared
@State private var showDownloadConfirmation = false

public var body: some View {
ZStack {
Expand Down Expand Up @@ -248,8 +249,42 @@ struct ModelDownloadView: View {
Spacer()
.frame(height: 16)

Button("Download Model", action: downloadManager.startDownload)
.buttonStyle(.PrimaryButton)
Button("Download Model") {
showDownloadConfirmation = true
}
.buttonStyle(.PrimaryButton)
.sheet(isPresented: $showDownloadConfirmation) {
SheetWrapper {
HStack {
Spacer()
CloseButton(action: { showDownloadConfirmation = false })
}
Spacer()
VStack(spacing: 20) {
Text("Download Model")
.font(.title())

Text("The model requires 4.21GB of storage space. Would you like to proceed with the download?")
.multilineTextAlignment(.center)
.font(.body())

VStack(spacing: 12) {
Button {
showDownloadConfirmation = false
downloadManager.startDownload()
} label: {
HStack {
Image(systemName: "arrow.down.circle.fill")
Text("Start Download")
}
}
.buttonStyle(.PrimaryButton)
}
}
.padding()
Spacer()
}
}
}

if let error = downloadManager.downloadError {
Expand Down
2 changes: 1 addition & 1 deletion OLMoE.swift/Views/UnsupportedDeviceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct UnsupportedDeviceView: View {
.sheet(isPresented: $showWebView, onDismiss: nil) {
SheetWrapper {
WebViewWithBanner(
url: URL(string: "https://playground.allenai.org/?model=olmoe-0125")!,
url: URL(string: AppConstants.Model.playgroundURL)!,
onDismiss: { showWebView = false }
)
}
Expand Down

0 comments on commit d6c1ce6

Please sign in to comment.