Rename Correct Spellings to Vocabulary and update related terminology
This commit is contained in:
parent
e74e6c1df5
commit
fe842de807
@ -24,7 +24,7 @@ class CustomVocabularyService {
|
||||
}
|
||||
|
||||
do {
|
||||
let items = try JSONDecoder().decode([DictionaryItem].self, from: data)
|
||||
let items = try JSONDecoder().decode([VocabularyWord].self, from: data)
|
||||
let words = items.map { $0.word }
|
||||
return words.isEmpty ? nil : words
|
||||
} catch {
|
||||
|
||||
@ -4,7 +4,7 @@ import UniformTypeIdentifiers
|
||||
|
||||
struct DictionaryExportData: Codable {
|
||||
let version: String
|
||||
let dictionaryItems: [String]
|
||||
let vocabularyWords: [String]
|
||||
let wordReplacements: [String: String]
|
||||
let exportDate: Date
|
||||
}
|
||||
@ -19,7 +19,7 @@ class DictionaryImportExportService {
|
||||
func exportDictionary() {
|
||||
var dictionaryWords: [String] = []
|
||||
if let data = UserDefaults.standard.data(forKey: dictionaryItemsKey),
|
||||
let items = try? JSONDecoder().decode([DictionaryItem].self, from: data) {
|
||||
let items = try? JSONDecoder().decode([VocabularyWord].self, from: data) {
|
||||
dictionaryWords = items.map { $0.word }
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ class DictionaryImportExportService {
|
||||
|
||||
let exportData = DictionaryExportData(
|
||||
version: version,
|
||||
dictionaryItems: dictionaryWords,
|
||||
vocabularyWords: dictionaryWords,
|
||||
wordReplacements: wordReplacements,
|
||||
exportDate: Date()
|
||||
)
|
||||
@ -45,7 +45,7 @@ class DictionaryImportExportService {
|
||||
savePanel.allowedContentTypes = [UTType.json]
|
||||
savePanel.nameFieldStringValue = "VoiceInk_Dictionary.json"
|
||||
savePanel.title = "Export Dictionary Data"
|
||||
savePanel.message = "Choose a location to save your dictionary items and word replacements."
|
||||
savePanel.message = "Choose a location to save your vocabulary and word replacements."
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if savePanel.runModal() == .OK {
|
||||
@ -88,9 +88,9 @@ class DictionaryImportExportService {
|
||||
decoder.dateDecodingStrategy = .iso8601
|
||||
let importedData = try decoder.decode(DictionaryExportData.self, from: jsonData)
|
||||
|
||||
var existingItems: [DictionaryItem] = []
|
||||
var existingItems: [VocabularyWord] = []
|
||||
if let data = UserDefaults.standard.data(forKey: self.dictionaryItemsKey),
|
||||
let items = try? JSONDecoder().decode([DictionaryItem].self, from: data) {
|
||||
let items = try? JSONDecoder().decode([VocabularyWord].self, from: data) {
|
||||
existingItems = items
|
||||
}
|
||||
|
||||
@ -98,9 +98,9 @@ class DictionaryImportExportService {
|
||||
let originalExistingCount = existingItems.count
|
||||
var newWordsAdded = 0
|
||||
|
||||
for importedWord in importedData.dictionaryItems {
|
||||
for importedWord in importedData.vocabularyWords {
|
||||
if !existingWordsLower.contains(importedWord.lowercased()) {
|
||||
existingItems.append(DictionaryItem(word: importedWord))
|
||||
existingItems.append(VocabularyWord(word: importedWord))
|
||||
newWordsAdded += 1
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ class DictionaryImportExportService {
|
||||
UserDefaults.standard.set(existingReplacements, forKey: self.wordReplacementsKey)
|
||||
|
||||
var message = "Dictionary data imported successfully from \(url.lastPathComponent).\n\n"
|
||||
message += "Dictionary Items: \(newWordsAdded) added, \(originalExistingCount) kept\n"
|
||||
message += "Vocabulary Words: \(newWordsAdded) added, \(originalExistingCount) kept\n"
|
||||
message += "Word Replacements: \(addedCount) added, \(updatedCount) updated"
|
||||
|
||||
self.showAlert(title: "Import Successful", message: message)
|
||||
|
||||
@ -32,7 +32,7 @@ struct VoiceInkExportedSettings: Codable {
|
||||
let version: String
|
||||
let customPrompts: [CustomPrompt]
|
||||
let powerModeConfigs: [PowerModeConfig]
|
||||
let dictionaryItems: [DictionaryItem]?
|
||||
let vocabularyWords: [VocabularyWord]?
|
||||
let wordReplacements: [String: String]?
|
||||
let generalSettings: GeneralSettings?
|
||||
let customEmojis: [String]?
|
||||
@ -78,9 +78,9 @@ class ImportExportService {
|
||||
// Export custom models
|
||||
let customModels = CustomModelManager.shared.customModels
|
||||
|
||||
var exportedDictionaryItems: [DictionaryItem]? = nil
|
||||
var exportedDictionaryItems: [VocabularyWord]? = nil
|
||||
if let data = UserDefaults.standard.data(forKey: dictionaryItemsKey),
|
||||
let items = try? JSONDecoder().decode([DictionaryItem].self, from: data) {
|
||||
let items = try? JSONDecoder().decode([VocabularyWord].self, from: data) {
|
||||
exportedDictionaryItems = items
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ class ImportExportService {
|
||||
version: currentSettingsVersion,
|
||||
customPrompts: exportablePrompts,
|
||||
powerModeConfigs: powerConfigs,
|
||||
dictionaryItems: exportedDictionaryItems,
|
||||
vocabularyWords: exportedDictionaryItems,
|
||||
wordReplacements: exportedWordReplacements,
|
||||
generalSettings: generalSettingsToExport,
|
||||
customEmojis: emojiManager.customEmojis,
|
||||
@ -203,12 +203,12 @@ class ImportExportService {
|
||||
}
|
||||
}
|
||||
|
||||
if let itemsToImport = importedSettings.dictionaryItems {
|
||||
if let itemsToImport = importedSettings.vocabularyWords {
|
||||
if let encoded = try? JSONEncoder().encode(itemsToImport) {
|
||||
UserDefaults.standard.set(encoded, forKey: "CustomVocabularyItems")
|
||||
}
|
||||
} else {
|
||||
print("No custom vocabulary items (for spelling) found in the imported file. Existing items remain unchanged.")
|
||||
print("No vocabulary words found in the imported file. Existing items remain unchanged.")
|
||||
}
|
||||
|
||||
if let replacementsToImport = importedSettings.wordReplacements {
|
||||
|
||||
@ -6,7 +6,7 @@ struct DictionarySettingsView: View {
|
||||
|
||||
enum DictionarySection: String, CaseIterable {
|
||||
case replacements = "Word Replacements"
|
||||
case spellings = "Correct Spellings"
|
||||
case spellings = "Vocabulary"
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
@ -90,7 +90,7 @@ struct DictionarySettingsView: View {
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Import dictionary items and word replacements")
|
||||
.help("Import vocabulary and word replacements")
|
||||
|
||||
Button(action: {
|
||||
DictionaryImportExportService.shared.exportDictionary()
|
||||
@ -100,7 +100,7 @@ struct DictionarySettingsView: View {
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.help("Export dictionary items and word replacements")
|
||||
.help("Export vocabulary and word replacements")
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ struct DictionarySettingsView: View {
|
||||
VStack(alignment: .leading, spacing: 20) {
|
||||
switch selectedSection {
|
||||
case .spellings:
|
||||
DictionaryView(whisperPrompt: whisperPrompt)
|
||||
VocabularyView(whisperPrompt: whisperPrompt)
|
||||
.background(CardBackground(isSelected: false))
|
||||
case .replacements:
|
||||
WordReplacementView()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import SwiftUI
|
||||
|
||||
struct DictionaryItem: Identifiable, Hashable, Codable {
|
||||
struct VocabularyWord: Identifiable, Hashable, Codable {
|
||||
var word: String
|
||||
|
||||
var id: String { word }
|
||||
@ -27,13 +27,13 @@ struct DictionaryItem: Identifiable, Hashable, Codable {
|
||||
}
|
||||
}
|
||||
|
||||
enum DictionarySortMode: String {
|
||||
enum VocabularySortMode: String {
|
||||
case wordAsc = "wordAsc"
|
||||
case wordDesc = "wordDesc"
|
||||
}
|
||||
|
||||
class DictionaryManager: ObservableObject {
|
||||
@Published var items: [DictionaryItem] = []
|
||||
class VocabularyManager: ObservableObject {
|
||||
@Published var items: [VocabularyWord] = []
|
||||
private let saveKey = "CustomVocabularyItems"
|
||||
private let whisperPrompt: WhisperPrompt
|
||||
|
||||
@ -45,7 +45,7 @@ class DictionaryManager: ObservableObject {
|
||||
private func loadItems() {
|
||||
guard let data = UserDefaults.standard.data(forKey: saveKey) else { return }
|
||||
|
||||
if let savedItems = try? JSONDecoder().decode([DictionaryItem].self, from: data) {
|
||||
if let savedItems = try? JSONDecoder().decode([VocabularyWord].self, from: data) {
|
||||
items = savedItems
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,7 @@ class DictionaryManager: ObservableObject {
|
||||
return
|
||||
}
|
||||
|
||||
let newItem = DictionaryItem(word: normalizedWord)
|
||||
let newItem = VocabularyWord(word: normalizedWord)
|
||||
items.insert(newItem, at: 0)
|
||||
saveItems()
|
||||
}
|
||||
@ -77,36 +77,36 @@ class DictionaryManager: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
struct DictionaryView: View {
|
||||
@StateObject private var dictionaryManager: DictionaryManager
|
||||
struct VocabularyView: View {
|
||||
@StateObject private var vocabularyManager: VocabularyManager
|
||||
@ObservedObject var whisperPrompt: WhisperPrompt
|
||||
@State private var newWord = ""
|
||||
@State private var showAlert = false
|
||||
@State private var alertMessage = ""
|
||||
@State private var sortMode: DictionarySortMode = .wordAsc
|
||||
@State private var sortMode: VocabularySortMode = .wordAsc
|
||||
|
||||
init(whisperPrompt: WhisperPrompt) {
|
||||
self.whisperPrompt = whisperPrompt
|
||||
_dictionaryManager = StateObject(wrappedValue: DictionaryManager(whisperPrompt: whisperPrompt))
|
||||
_vocabularyManager = StateObject(wrappedValue: VocabularyManager(whisperPrompt: whisperPrompt))
|
||||
|
||||
if let savedSort = UserDefaults.standard.string(forKey: "dictionarySortMode"),
|
||||
let mode = DictionarySortMode(rawValue: savedSort) {
|
||||
if let savedSort = UserDefaults.standard.string(forKey: "vocabularySortMode"),
|
||||
let mode = VocabularySortMode(rawValue: savedSort) {
|
||||
_sortMode = State(initialValue: mode)
|
||||
}
|
||||
}
|
||||
|
||||
private var sortedItems: [DictionaryItem] {
|
||||
private var sortedItems: [VocabularyWord] {
|
||||
switch sortMode {
|
||||
case .wordAsc:
|
||||
return dictionaryManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedAscending }
|
||||
return vocabularyManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedAscending }
|
||||
case .wordDesc:
|
||||
return dictionaryManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedDescending }
|
||||
return vocabularyManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedDescending }
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleSort() {
|
||||
sortMode = (sortMode == .wordAsc) ? .wordDesc : .wordAsc
|
||||
UserDefaults.standard.set(sortMode.rawValue, forKey: "dictionarySortMode")
|
||||
UserDefaults.standard.set(sortMode.rawValue, forKey: "vocabularySortMode")
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@ -124,7 +124,7 @@ struct DictionaryView: View {
|
||||
}
|
||||
|
||||
HStack(spacing: 8) {
|
||||
TextField("Add word to dictionary", text: $newWord)
|
||||
TextField("Add word to vocabulary", text: $newWord)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
.font(.system(size: 13))
|
||||
.onSubmit { addWords() }
|
||||
@ -140,11 +140,11 @@ struct DictionaryView: View {
|
||||
.help("Add word")
|
||||
}
|
||||
|
||||
if !dictionaryManager.items.isEmpty {
|
||||
if !vocabularyManager.items.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
Button(action: toggleSort) {
|
||||
HStack(spacing: 4) {
|
||||
Text("Dictionary Items (\(dictionaryManager.items.count))")
|
||||
Text("Vocabulary Words (\(vocabularyManager.items.count))")
|
||||
.font(.system(size: 12, weight: .medium))
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
@ -159,8 +159,8 @@ struct DictionaryView: View {
|
||||
ScrollView {
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 240, maximum: .infinity), spacing: 12)], alignment: .leading, spacing: 12) {
|
||||
ForEach(sortedItems) { item in
|
||||
DictionaryItemView(item: item) {
|
||||
dictionaryManager.removeWord(item.word)
|
||||
VocabularyWordView(item: item) {
|
||||
vocabularyManager.removeWord(item.word)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,7 +172,7 @@ struct DictionaryView: View {
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.alert("Dictionary", isPresented: $showAlert) {
|
||||
.alert("Vocabulary", isPresented: $showAlert) {
|
||||
Button("OK", role: .cancel) {}
|
||||
} message: {
|
||||
Text(alertMessage)
|
||||
@ -191,28 +191,28 @@ struct DictionaryView: View {
|
||||
guard !parts.isEmpty else { return }
|
||||
|
||||
if parts.count == 1, let word = parts.first {
|
||||
if dictionaryManager.items.contains(where: { $0.word.lowercased() == word.lowercased() }) {
|
||||
alertMessage = "'\(word)' is already in the dictionary"
|
||||
if vocabularyManager.items.contains(where: { $0.word.lowercased() == word.lowercased() }) {
|
||||
alertMessage = "'\(word)' is already in the vocabulary"
|
||||
showAlert = true
|
||||
return
|
||||
}
|
||||
dictionaryManager.addWord(word)
|
||||
vocabularyManager.addWord(word)
|
||||
newWord = ""
|
||||
return
|
||||
}
|
||||
|
||||
for word in parts {
|
||||
let lower = word.lowercased()
|
||||
if !dictionaryManager.items.contains(where: { $0.word.lowercased() == lower }) {
|
||||
dictionaryManager.addWord(word)
|
||||
if !vocabularyManager.items.contains(where: { $0.word.lowercased() == lower }) {
|
||||
vocabularyManager.addWord(word)
|
||||
}
|
||||
}
|
||||
newWord = ""
|
||||
}
|
||||
}
|
||||
|
||||
struct DictionaryItemView: View {
|
||||
let item: DictionaryItem
|
||||
struct VocabularyWordView: View {
|
||||
let item: VocabularyWord
|
||||
let onDelete: () -> Void
|
||||
@State private var isHovered = false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user