Skip to content

Commit

Permalink
nearly finish export flow ui
Browse files Browse the repository at this point in the history
  • Loading branch information
pdtxie committed Mar 22, 2024
1 parent 389d054 commit caa98e0
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 83 deletions.
229 changes: 147 additions & 82 deletions CubeTime/Sessions/ImportExport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,175 @@ struct ImportFlow: View {
}

struct ExportFlowPickSessions: View {
@EnvironmentObject var exportViewModel: ExportViewModel
@EnvironmentObject var stopwatchManager: StopwatchManager
@StateObject var exportViewModel: ExportViewModel = ExportViewModel()

@Environment(\.horizontalSizeClass) var hSizeClass

@State private var showNext = false

let sessions: FetchedResults<Session>

var body: some View {
ScrollView {
ForEach(sessions) { session in
let selected = exportViewModel.selectedSessions.contains(session)

SessionCardBase(item: session,
pinned: false,
sessionType: SessionType(rawValue: session.sessionType)!,
name: session.name ?? "Unknown session name",
scrambleType: Int(session.scrambleType),
solveCount: 0,
selected: selected,
forExportUse: true)
.onTapGesture {
withAnimation(Animation.customDampedSpring) {
if selected {
exportViewModel.selectedSessions.remove(session)
} else {
exportViewModel.selectedSessions.insert(session)
ZStack {
BackgroundColour()
.ignoresSafeArea()

VStack(spacing: 4) {
Text("Select Sessions for Export")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .bottomLeading)
.padding(.top, 32)
.padding(.leading)

VStack {
ScrollView {
ForEach(sessions) { session in
let selected = exportViewModel.selectedSessions.contains(session)

SessionCardBase(item: session,
pinned: false,
sessionType: SessionType(rawValue: session.sessionType)!,
name: session.name ?? "Unknown session name",
scrambleType: Int(session.scrambleType),
solveCount: 0,
selected: selected,
forExportUse: true)
.onTapGesture {
withAnimation(Animation.customDampedSpring) {
if selected {
exportViewModel.selectedSessions.remove(session)
} else {
exportViewModel.selectedSessions.insert(session)
}
}
}
.padding(.horizontal)
}
}
.padding(.horizontal)
}
}
}
.navigationTitle("Export Sessions")
.overlay(alignment: .bottomTrailing) {
CTButton(type: exportViewModel.selectedSessions.count == 0 ? .disabled : .coloured(nil), size: .large, onTapRun: { exportViewModel.exportFlowState = .pickingFormats }) {
HStack {
Text("Continue")

Image(systemName: "arrow.forward")
.font(.subheadline)
.navigationTitle("Export Sessions")
.navigationBarTitleDisplayMode(.inline)
.overlay(alignment: .bottomTrailing) {
NavigationLink(destination: ExportFlowPickFormats().environmentObject(exportViewModel), isActive: $showNext) { EmptyView() }

CTButton(type: exportViewModel.selectedSessions.count == 0 ? .disabled : .coloured(nil), size: .large, onTapRun: { exportViewModel.exportFlowState = .pickingFormats
showNext = true
}) {
HStack {
Text("Continue")

Image(systemName: "arrow.forward")
.font(.subheadline)
}
}
.padding(.horizontal)
.if(!(UIDevice.deviceIsPad && hSizeClass == .regular)) { view in
view
.padding(.bottom, 58)
.padding(.bottom, UIDevice.hasBottomBar ? 0 : nil)
}
.if(UIDevice.deviceIsPad && hSizeClass == .regular) { view in
view
.padding(.bottom, 8)
}
}
.padding(.horizontal)
}
}
}


struct ExportFlowPickFormats: View {
@EnvironmentObject var exportViewModel: ExportViewModel
@State var showFilePathSave = false

@State private var showNext = false

@Environment(\.horizontalSizeClass) var hSizeClass


var body: some View {
let zippedArray = Array(zip(exportViewModel.allFormats.indices, exportViewModel.allFormats))
ForEach(zippedArray, id: \.0) { (_, format) in
let indexInSelected = exportViewModel.selectedFormats.firstIndex(where: {$0 === format})
HStack {
Text(format.getName())
Spacer()
Image(systemName: indexInSelected != nil ? "checkmark.circle.fill" : "checkmark.circle")
}
.onTapGesture {
withAnimation(Animation.customDampedSpring) {
if let indexInSelected {
exportViewModel.selectedFormats.remove(at: indexInSelected)
} else {
exportViewModel.selectedFormats.append(format)

ZStack {
BackgroundColour()
.ignoresSafeArea()

VStack(spacing: 4) {
Text("Select Export Types")
.font(.headline)
.frame(maxWidth: .infinity, alignment: .bottomLeading)
.padding(.top, 32)
.padding(.leading)

VStack {
ForEach(zippedArray, id: \.0) { (_, format) in
let indexInSelected = exportViewModel.selectedFormats.firstIndex(where: {$0 === format})

HStack {
Text(format.getName())
.font(.title2.weight(.semibold))
.foregroundColor(Color("dark"))

Spacer()

if indexInSelected != nil {
Image(systemName: "checkmark.circle.fill")
.font(.body.weight(.semibold))
.foregroundStyle(Color("accent"), Color("overlay0"))
.padding(.trailing, 8)
}
}
.padding(10)
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.fill(indexInSelected != nil ? Color("indent1") : Color("overlay0"))
)
.padding(.horizontal)

.onTapGesture {
withAnimation(Animation.customDampedSpring) {
if let indexInSelected {
exportViewModel.selectedFormats.remove(at: indexInSelected)
} else {
exportViewModel.selectedFormats.append(format)
}
}
}
}

Spacer()
}
}
}
.navigationTitle("Export Sessions")

CTButton(type: exportViewModel.selectedSessions.count == 0 ? .disabled : .halfcoloured(nil), size: .large, onTapRun: { showFilePathSave = true }) {
HStack {
Text("Confirm Export")
.overlay(alignment: .bottomTrailing) {
if case let ExportFlowState.finished(result) = exportViewModel.exportFlowState {
NavigationLink(destination: ExportFlowFinished(result: result).environmentObject(exportViewModel), isActive: Binding.constant(true)) { EmptyView() }
}


Image(systemName: "arrow.forward")
CTButton(type: exportViewModel.selectedFormats.count == 0 ? .disabled : .coloured(nil), size: .large, onTapRun: {
showFilePathSave = true
showNext = true
}) {
HStack {
Text("Confirm Export")

Image(systemName: "arrow.forward")
}
}
.padding(.horizontal)
.if(!(UIDevice.deviceIsPad && hSizeClass == .regular)) { view in
view
.padding(.bottom, 58)
.padding(.bottom, UIDevice.hasBottomBar ? 0 : nil)
}
.if(UIDevice.deviceIsPad && hSizeClass == .regular) { view in
view
.padding(.bottom, 8)
}
}
}
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.trailing)
.fileExporter(isPresented: $showFilePathSave, documents: exportViewModel.selectedFormats, contentType: .data ,onCompletion: { result in
exportViewModel.finishExport(result: result)
})
Expand All @@ -106,41 +195,17 @@ struct ExportFlowFinished: View {

var result: Result<[URL], Error>

var body: some View {
switch result {
case .success:
Text("Export Success!")
case .failure(let failure):
Text("Export failed: \(failure.localizedDescription)")
}
}
}


struct ExportFlow: View {
@EnvironmentObject var stopwatchManager: StopwatchManager
@StateObject var exportViewModel: ExportViewModel = ExportViewModel()

let sessions: FetchedResults<Session>

var body: some View {
ZStack {
BackgroundColour()
.ignoresSafeArea()

VStack {
switch exportViewModel.exportFlowState {
case .pickingSessions:
ExportFlowPickSessions(sessions: sessions)
case .pickingFormats:
ExportFlowPickFormats()
case .finished(let result):
ExportFlowFinished(result: result)
}
switch result {
case .success:
Text("Export Success!")

case .failure(let failure):
Text("Export failed: \(failure.localizedDescription)")
}
.safeAreaInset(safeArea: .tabBar)
.environmentObject(exportViewModel)

}
}
}
2 changes: 1 addition & 1 deletion CubeTime/Sessions/SessionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct SessionsView: View {
}
.background(
Group {
NavigationLink(destination: ExportFlow(sessions: sessions), isActive: $showExport) { EmptyView() }
NavigationLink(destination: ExportFlowPickSessions(sessions: sessions), isActive: $showExport) { EmptyView() }
NavigationLink(destination: ImportFlow(), isActive: $showImport) { EmptyView() }
}
)
Expand Down

0 comments on commit caa98e0

Please sign in to comment.