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

Redesign #31

Merged
merged 5 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import PackageDescription
let package = Package(
name: "Flashcards",
dependencies: [
.package(url: "https://github.com/AparokshaUI/Adwaita", branch: "0.2.3"),
.package(url: "https://github.com/AparokshaUI/Adwaita", branch: "main"),
.package(url: "https://github.com/AparokshaUI/Localized", from: "0.2.2")
],
targets: [
Expand Down
36 changes: 1 addition & 35 deletions Sources/Flashcards.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,15 @@ struct Flashcards: App {

@State("sets", folder: "io.github.david_swift.Flashcards", forceUpdates: true)
private var sets: [FlashcardsSet] = []
@State private var copied = Signal()
let id = "io.github.david_swift.Flashcards"
var app: GTUIApp!

var scene: Scene {
Window(id: "main") { window in
ContentView(copied: $copied, sets: $sets, app: app, window: window)
ContentView(sets: $sets, app: app, window: window)
}
.title("Memorize")
.quitShortcut()
.overlay {
AboutWindow(id: "about", appName: "Memorize", developer: "david-swift", version: "0.1.5")
.icon(.custom(name: "io.github.david_swift.Flashcards"))
.website(.init(string: "https://github.com/david-swift/Memorize"))
.issues(.init(string: "https://github.com/david-swift/Memorize/issues"))
for (index, set) in sets.enumerated() {
// Import flashcards and add to a set.
Window(id: "import-\(set.id)", open: 0) { window in
ImportView(
set: .init { set } set: { sets[safe: index] = $0 },
window: window
)
}
.defaultSize(width: 500, height: 500)
.keyboardShortcut("Escape") { $0.close() }

// Export a set.
Window(id: "export-\(set.id)", open: 0) { window in
ExportView(copied: $copied, set: set, window: window)
}
.title(Loc.export(title: set.name))
.defaultSize(width: 500, height: 500)
.keyboardShortcut("Escape") { $0.close() }

// Delete a set.
Window(id: "delete-\(set.id)", open: 0) { window in
DeleteView(set: set, window: window) { sets = sets.filter { $0.id != set.id } }
}
.defaultSize(width: 450, height: 350)
.resizable(false)
.keyboardShortcut("Escape") { $0.close() }
}
}
}

}
33 changes: 4 additions & 29 deletions Sources/Model/FlashcardsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,18 @@

import Adwaita

enum FlashcardsView: ViewSwitcherOption, Codable {
enum FlashcardsView: CustomStringConvertible {

case overview
case study
case test
case study(set: String)
case test(set: String)

var title: String {
var description: String {
switch self {
case .overview:
Loc.overview
case .study:
Loc.studySwitcher
case .test:
Loc.test
}
}

var icon: Icon {
switch self {
case .overview:
return .default(icon: .viewReveal)
case .study:
return .default(icon: .mediaPlaybackStart)
case .test:
return .default(icon: .findLocation)
}
}

init?(title: String) {
switch title {
case Loc.studySwitcher:
self = .study
case Loc.test:
self = .test
default:
self = .overview
}
}

}
24 changes: 18 additions & 6 deletions Sources/Model/Localized.yml
Original file line number Diff line number Diff line change
Expand Up @@ -588,12 +588,6 @@ semicolon:
it: Punto e virgola
pt_BR: Ponto e vírgula

editSetDescription:
en: Edit the set's content and title
de: Bearbeite den Inhalt und Titel des Sets
it: Modifica il contenuto e il titolo del Set
pt_BR: Editar conteúdo e título do set

createSet:
en: Create Set
de: Set erstellen
Expand All @@ -604,3 +598,21 @@ copied:
en: Contents copied to clipboard
de: Inhalte wurden kopiert
it: Contenuto copiato negli appunti

flashcards(count):
en(count == "1"): 1 flashcard
en: (count) flashcards
de(count == "1"): 1 Karteikarte
de: (count) Karteikarten

activeStudySession:
en: Active Study Session
de: Aktive Lerneinheit

activeStudySessionDescription:
en: You are currently in a study session
de: Du befindest dich in einer Lerneinheit

toggleSidebar:
en: Toggle Sidebar
de: Seitenleiste ein- und ausblenden
129 changes: 81 additions & 48 deletions Sources/View/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import Foundation

struct ContentView: WindowView {

@Binding var copied: Signal
@Binding var sets: [FlashcardsSet]
@State("selected-set")
private var selectedSet = ""
@State("flashcards-view")
private var flashcardsView: FlashcardsView = .overview
@State private var flashcardsView: NavigationStack<FlashcardsView> = .init()
@State private var filter: String?
@State private var editMode = false
@State("width")
Expand All @@ -23,34 +21,48 @@ struct ContentView: WindowView {
private var height = 550
@State("maximized")
private var maximized = false
@State private var sidebarVisible = true
var app: GTUIApp
var window: GTUIApplicationWindow

var smallWindow: Bool { width < 600 }

var view: Body {
OverlaySplitView(visible: .constant(flashcardsView == .overview && !editMode && !sets.isEmpty)) {
sidebar
} content: {
content
.topToolbar(visible: !editMode || flashcardsView != .overview) {
ToolbarView(
flashcardsView: $flashcardsView,
sets: $sets,
selectedSet: $selectedSet,
filter: $filter,
app: app,
window: window,
addSet: addSet
).content
NavigationView($flashcardsView, Loc.overview) { view in
Bin()
.child {
switch view {
case let .study(set):
ViewStack(element: set) { _ in
StudyView(set: binding(id: set))
}
case let .test(set):
TestView(set: binding(id: set))
}
}
.topToolbar {
HeaderBar.empty()
}
} initialView: {
OverlaySplitView(visible: .init { sidebarVisible || !smallWindow } set: { sidebarVisible = $0 }) {
sidebar
} content: {
content
}
.collapsed(smallWindow)
}
.toast(Loc.copied, signal: copied)
}

var sidebar: View {
ScrollView {
List(
sets.map { ($0, $0.score(filter)) }.sorted { $0.1 > $1.1 }.filter { $0.1 != 0 }.map { $0.0 },
selection: $selectedSet
selection: .init {
selectedSet
} set: { newValue in
selectedSet = newValue
sidebarVisible = false
}
) { set in
Text(set.name)
.ellipsize()
Expand All @@ -64,12 +76,11 @@ struct ContentView: WindowView {
SearchEntry()
.placeholderText(Loc.filterSets)
.text(.init { filter ?? "" } set: { filter = $0 })
.focused(.constant(!editMode && flashcardsView == .overview))
.focused(.constant(filter != nil))
.padding(5, .horizontal.add(.bottom))
}
.topToolbar {
ToolbarView(
flashcardsView: $flashcardsView,
sets: $sets,
selectedSet: $selectedSet,
filter: $filter,
Expand All @@ -83,37 +94,50 @@ struct ContentView: WindowView {
@ViewBuilder var content: Body {
if let index = sets.firstIndex(where: { $0.id == selectedSet }), let set = sets[safe: index] {
let binding = Binding<FlashcardsSet> { sets[safe: index] ?? .init() } set: { sets[safe: index] = $0 }
switch flashcardsView {
case .overview:
SetOverview(set: binding, editMode: $editMode, app: app, window: window)
case .study:
ViewStack(element: set) { _ in
StudyView(set: binding)
}
case .test:
TestView(set: binding)
SetOverview(
set: binding,
editMode: $editMode,
flashcardsView: $flashcardsView,
sidebarVisible: $sidebarVisible,
smallWindow: smallWindow
) {
sets = sets.filter { $0.id != set.id }
}
} else if !sets.isEmpty {
StatusPage(
Loc.noSelection,
icon: .custom(name: "io.github.david_swift.Flashcards.set-symbolic"),
description: Loc.noSelectionDescription
)
.centerMinSize()
} else {
StatusPage(
Loc.noSets,
icon: .custom(name: "io.github.david_swift.Flashcards.set-symbolic"),
description: Loc.noSetsDescription
) {
Button(Loc.createSet) {
addSet()
VStack {
if !sets.isEmpty {
StatusPage(
Loc.noSelection,
icon: .custom(name: "io.github.david_swift.Flashcards.set-symbolic"),
description: Loc.noSelectionDescription
)
.centerMinSize()
} else {
StatusPage(
Loc.noSets,
icon: .custom(name: "io.github.david_swift.Flashcards.set-symbolic"),
description: Loc.noSetsDescription
) {
Button(Loc.createSet) {
addSet()
}
.style("pill")
.style("suggested-action")
.horizontalCenter()
}
.centerMinSize()
}
}
.topToolbar {
HeaderBar.start {
if smallWindow {
Button(icon: .default(icon: .sidebarShow)) {
sidebarVisible.toggle()
}
.tooltip(Loc.toggleSidebar)
}
}
.style("pill")
.style("suggested-action")
.horizontalCenter()
}
.centerMinSize()
}
}

Expand All @@ -127,6 +151,15 @@ struct ContentView: WindowView {
let newSet = FlashcardsSet()
sets.insert(newSet, at: 0)
selectedSet = newSet.id
editMode = true
}

func binding(id: String) -> Binding<FlashcardsSet> {
.init {
sets.first { $0.id == id } ?? .init()
} set: { newValue in
sets[safe: sets.firstIndex { $0.id == id }] = newValue
}
}

}
6 changes: 3 additions & 3 deletions Sources/View/DeleteView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import Adwaita
struct DeleteView: View {

var set: FlashcardsSet
var window: GTUIWindow
var delete: () -> Void
var close: () -> Void

var view: Body {
ScrollView {
Expand All @@ -19,12 +19,12 @@ struct DeleteView: View {
.topToolbar {
HeaderBar(titleButtons: false) {
Button(Loc.cancel) {
window.close()
close()
}
} end: {
Button(Loc.delete) {
close()
delete()
window.close()
}
.style("destructive-action")
}
Expand Down
22 changes: 5 additions & 17 deletions Sources/View/EditView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ struct EditView: View {
@Binding var editMode: Bool
@State private var expanded = false
@State private var focusedFront: String?
var app: GTUIApp
var window: GTUIWindow
@State private var importFlashcards = false

var view: Body {
ScrollView {
Expand All @@ -27,20 +26,6 @@ struct EditView: View {
.vexpand()
.topToolbar {
HeaderBar(titleButtons: false) {
ViewStack(element: set) { _ in
HStack {
Button(icon: .default(icon: .userTrash)) {
app.addWindow("delete-\(set.id)", parent: window)
editMode = false
}
.tooltip(Loc.deleteSet)
Button(icon: .custom(name: "io.github.david_swift.Flashcards.share-symbolic")) {
app.addWindow("export-\(set.id)", parent: window)
}
.padding(10, .horizontal)
.tooltip(Loc.exportSet)
}
}
} end: {
Button(Loc.done) {
editMode = false
Expand Down Expand Up @@ -133,7 +118,10 @@ struct EditView: View {
) {
appendFlashcard()
} secondary: {
app.addWindow("import-\(set.id)", parent: window)
importFlashcards = true
}
.dialog(visible: $importFlashcards, width: 400, height: 500) {
ImportView(set: $set) { importFlashcards = false }
}
}

Expand Down
Loading
Loading