Rename Correct Spellings to Vocabulary and update related terminology

This commit is contained in:
Beingpax 2025-12-27 15:27:00 +05:45
parent e74e6c1df5
commit fe842de807
5 changed files with 49 additions and 49 deletions

View File

@ -24,7 +24,7 @@ class CustomVocabularyService {
} }
do { 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 } let words = items.map { $0.word }
return words.isEmpty ? nil : words return words.isEmpty ? nil : words
} catch { } catch {

View File

@ -4,7 +4,7 @@ import UniformTypeIdentifiers
struct DictionaryExportData: Codable { struct DictionaryExportData: Codable {
let version: String let version: String
let dictionaryItems: [String] let vocabularyWords: [String]
let wordReplacements: [String: String] let wordReplacements: [String: String]
let exportDate: Date let exportDate: Date
} }
@ -19,7 +19,7 @@ class DictionaryImportExportService {
func exportDictionary() { func exportDictionary() {
var dictionaryWords: [String] = [] var dictionaryWords: [String] = []
if let data = UserDefaults.standard.data(forKey: dictionaryItemsKey), 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 } dictionaryWords = items.map { $0.word }
} }
@ -29,7 +29,7 @@ class DictionaryImportExportService {
let exportData = DictionaryExportData( let exportData = DictionaryExportData(
version: version, version: version,
dictionaryItems: dictionaryWords, vocabularyWords: dictionaryWords,
wordReplacements: wordReplacements, wordReplacements: wordReplacements,
exportDate: Date() exportDate: Date()
) )
@ -45,7 +45,7 @@ class DictionaryImportExportService {
savePanel.allowedContentTypes = [UTType.json] savePanel.allowedContentTypes = [UTType.json]
savePanel.nameFieldStringValue = "VoiceInk_Dictionary.json" savePanel.nameFieldStringValue = "VoiceInk_Dictionary.json"
savePanel.title = "Export Dictionary Data" 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 { DispatchQueue.main.async {
if savePanel.runModal() == .OK { if savePanel.runModal() == .OK {
@ -88,9 +88,9 @@ class DictionaryImportExportService {
decoder.dateDecodingStrategy = .iso8601 decoder.dateDecodingStrategy = .iso8601
let importedData = try decoder.decode(DictionaryExportData.self, from: jsonData) let importedData = try decoder.decode(DictionaryExportData.self, from: jsonData)
var existingItems: [DictionaryItem] = [] var existingItems: [VocabularyWord] = []
if let data = UserDefaults.standard.data(forKey: self.dictionaryItemsKey), 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 existingItems = items
} }
@ -98,9 +98,9 @@ class DictionaryImportExportService {
let originalExistingCount = existingItems.count let originalExistingCount = existingItems.count
var newWordsAdded = 0 var newWordsAdded = 0
for importedWord in importedData.dictionaryItems { for importedWord in importedData.vocabularyWords {
if !existingWordsLower.contains(importedWord.lowercased()) { if !existingWordsLower.contains(importedWord.lowercased()) {
existingItems.append(DictionaryItem(word: importedWord)) existingItems.append(VocabularyWord(word: importedWord))
newWordsAdded += 1 newWordsAdded += 1
} }
} }
@ -147,7 +147,7 @@ class DictionaryImportExportService {
UserDefaults.standard.set(existingReplacements, forKey: self.wordReplacementsKey) UserDefaults.standard.set(existingReplacements, forKey: self.wordReplacementsKey)
var message = "Dictionary data imported successfully from \(url.lastPathComponent).\n\n" 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" message += "Word Replacements: \(addedCount) added, \(updatedCount) updated"
self.showAlert(title: "Import Successful", message: message) self.showAlert(title: "Import Successful", message: message)

View File

@ -32,7 +32,7 @@ struct VoiceInkExportedSettings: Codable {
let version: String let version: String
let customPrompts: [CustomPrompt] let customPrompts: [CustomPrompt]
let powerModeConfigs: [PowerModeConfig] let powerModeConfigs: [PowerModeConfig]
let dictionaryItems: [DictionaryItem]? let vocabularyWords: [VocabularyWord]?
let wordReplacements: [String: String]? let wordReplacements: [String: String]?
let generalSettings: GeneralSettings? let generalSettings: GeneralSettings?
let customEmojis: [String]? let customEmojis: [String]?
@ -78,9 +78,9 @@ class ImportExportService {
// Export custom models // Export custom models
let customModels = CustomModelManager.shared.customModels let customModels = CustomModelManager.shared.customModels
var exportedDictionaryItems: [DictionaryItem]? = nil var exportedDictionaryItems: [VocabularyWord]? = nil
if let data = UserDefaults.standard.data(forKey: dictionaryItemsKey), 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 exportedDictionaryItems = items
} }
@ -114,7 +114,7 @@ class ImportExportService {
version: currentSettingsVersion, version: currentSettingsVersion,
customPrompts: exportablePrompts, customPrompts: exportablePrompts,
powerModeConfigs: powerConfigs, powerModeConfigs: powerConfigs,
dictionaryItems: exportedDictionaryItems, vocabularyWords: exportedDictionaryItems,
wordReplacements: exportedWordReplacements, wordReplacements: exportedWordReplacements,
generalSettings: generalSettingsToExport, generalSettings: generalSettingsToExport,
customEmojis: emojiManager.customEmojis, 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) { if let encoded = try? JSONEncoder().encode(itemsToImport) {
UserDefaults.standard.set(encoded, forKey: "CustomVocabularyItems") UserDefaults.standard.set(encoded, forKey: "CustomVocabularyItems")
} }
} else { } 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 { if let replacementsToImport = importedSettings.wordReplacements {

View File

@ -6,7 +6,7 @@ struct DictionarySettingsView: View {
enum DictionarySection: String, CaseIterable { enum DictionarySection: String, CaseIterable {
case replacements = "Word Replacements" case replacements = "Word Replacements"
case spellings = "Correct Spellings" case spellings = "Vocabulary"
var description: String { var description: String {
switch self { switch self {
@ -90,7 +90,7 @@ struct DictionarySettingsView: View {
.foregroundColor(.blue) .foregroundColor(.blue)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.help("Import dictionary items and word replacements") .help("Import vocabulary and word replacements")
Button(action: { Button(action: {
DictionaryImportExportService.shared.exportDictionary() DictionaryImportExportService.shared.exportDictionary()
@ -100,7 +100,7 @@ struct DictionarySettingsView: View {
.foregroundColor(.blue) .foregroundColor(.blue)
} }
.buttonStyle(.plain) .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) { VStack(alignment: .leading, spacing: 20) {
switch selectedSection { switch selectedSection {
case .spellings: case .spellings:
DictionaryView(whisperPrompt: whisperPrompt) VocabularyView(whisperPrompt: whisperPrompt)
.background(CardBackground(isSelected: false)) .background(CardBackground(isSelected: false))
case .replacements: case .replacements:
WordReplacementView() WordReplacementView()

View File

@ -1,6 +1,6 @@
import SwiftUI import SwiftUI
struct DictionaryItem: Identifiable, Hashable, Codable { struct VocabularyWord: Identifiable, Hashable, Codable {
var word: String var word: String
var id: String { word } var id: String { word }
@ -27,13 +27,13 @@ struct DictionaryItem: Identifiable, Hashable, Codable {
} }
} }
enum DictionarySortMode: String { enum VocabularySortMode: String {
case wordAsc = "wordAsc" case wordAsc = "wordAsc"
case wordDesc = "wordDesc" case wordDesc = "wordDesc"
} }
class DictionaryManager: ObservableObject { class VocabularyManager: ObservableObject {
@Published var items: [DictionaryItem] = [] @Published var items: [VocabularyWord] = []
private let saveKey = "CustomVocabularyItems" private let saveKey = "CustomVocabularyItems"
private let whisperPrompt: WhisperPrompt private let whisperPrompt: WhisperPrompt
@ -45,7 +45,7 @@ class DictionaryManager: ObservableObject {
private func loadItems() { private func loadItems() {
guard let data = UserDefaults.standard.data(forKey: saveKey) else { return } 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 items = savedItems
} }
} }
@ -62,7 +62,7 @@ class DictionaryManager: ObservableObject {
return return
} }
let newItem = DictionaryItem(word: normalizedWord) let newItem = VocabularyWord(word: normalizedWord)
items.insert(newItem, at: 0) items.insert(newItem, at: 0)
saveItems() saveItems()
} }
@ -77,36 +77,36 @@ class DictionaryManager: ObservableObject {
} }
} }
struct DictionaryView: View { struct VocabularyView: View {
@StateObject private var dictionaryManager: DictionaryManager @StateObject private var vocabularyManager: VocabularyManager
@ObservedObject var whisperPrompt: WhisperPrompt @ObservedObject var whisperPrompt: WhisperPrompt
@State private var newWord = "" @State private var newWord = ""
@State private var showAlert = false @State private var showAlert = false
@State private var alertMessage = "" @State private var alertMessage = ""
@State private var sortMode: DictionarySortMode = .wordAsc @State private var sortMode: VocabularySortMode = .wordAsc
init(whisperPrompt: WhisperPrompt) { init(whisperPrompt: WhisperPrompt) {
self.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"), if let savedSort = UserDefaults.standard.string(forKey: "vocabularySortMode"),
let mode = DictionarySortMode(rawValue: savedSort) { let mode = VocabularySortMode(rawValue: savedSort) {
_sortMode = State(initialValue: mode) _sortMode = State(initialValue: mode)
} }
} }
private var sortedItems: [DictionaryItem] { private var sortedItems: [VocabularyWord] {
switch sortMode { switch sortMode {
case .wordAsc: case .wordAsc:
return dictionaryManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedAscending } return vocabularyManager.items.sorted { $0.word.localizedCaseInsensitiveCompare($1.word) == .orderedAscending }
case .wordDesc: 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() { private func toggleSort() {
sortMode = (sortMode == .wordAsc) ? .wordDesc : .wordAsc sortMode = (sortMode == .wordAsc) ? .wordDesc : .wordAsc
UserDefaults.standard.set(sortMode.rawValue, forKey: "dictionarySortMode") UserDefaults.standard.set(sortMode.rawValue, forKey: "vocabularySortMode")
} }
var body: some View { var body: some View {
@ -124,7 +124,7 @@ struct DictionaryView: View {
} }
HStack(spacing: 8) { HStack(spacing: 8) {
TextField("Add word to dictionary", text: $newWord) TextField("Add word to vocabulary", text: $newWord)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
.font(.system(size: 13)) .font(.system(size: 13))
.onSubmit { addWords() } .onSubmit { addWords() }
@ -140,11 +140,11 @@ struct DictionaryView: View {
.help("Add word") .help("Add word")
} }
if !dictionaryManager.items.isEmpty { if !vocabularyManager.items.isEmpty {
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
Button(action: toggleSort) { Button(action: toggleSort) {
HStack(spacing: 4) { HStack(spacing: 4) {
Text("Dictionary Items (\(dictionaryManager.items.count))") Text("Vocabulary Words (\(vocabularyManager.items.count))")
.font(.system(size: 12, weight: .medium)) .font(.system(size: 12, weight: .medium))
.foregroundColor(.secondary) .foregroundColor(.secondary)
@ -159,8 +159,8 @@ struct DictionaryView: View {
ScrollView { ScrollView {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 240, maximum: .infinity), spacing: 12)], alignment: .leading, spacing: 12) { LazyVGrid(columns: [GridItem(.adaptive(minimum: 240, maximum: .infinity), spacing: 12)], alignment: .leading, spacing: 12) {
ForEach(sortedItems) { item in ForEach(sortedItems) { item in
DictionaryItemView(item: item) { VocabularyWordView(item: item) {
dictionaryManager.removeWord(item.word) vocabularyManager.removeWord(item.word)
} }
} }
} }
@ -172,7 +172,7 @@ struct DictionaryView: View {
} }
} }
.padding() .padding()
.alert("Dictionary", isPresented: $showAlert) { .alert("Vocabulary", isPresented: $showAlert) {
Button("OK", role: .cancel) {} Button("OK", role: .cancel) {}
} message: { } message: {
Text(alertMessage) Text(alertMessage)
@ -191,28 +191,28 @@ struct DictionaryView: View {
guard !parts.isEmpty else { return } guard !parts.isEmpty else { return }
if parts.count == 1, let word = parts.first { if parts.count == 1, let word = parts.first {
if dictionaryManager.items.contains(where: { $0.word.lowercased() == word.lowercased() }) { if vocabularyManager.items.contains(where: { $0.word.lowercased() == word.lowercased() }) {
alertMessage = "'\(word)' is already in the dictionary" alertMessage = "'\(word)' is already in the vocabulary"
showAlert = true showAlert = true
return return
} }
dictionaryManager.addWord(word) vocabularyManager.addWord(word)
newWord = "" newWord = ""
return return
} }
for word in parts { for word in parts {
let lower = word.lowercased() let lower = word.lowercased()
if !dictionaryManager.items.contains(where: { $0.word.lowercased() == lower }) { if !vocabularyManager.items.contains(where: { $0.word.lowercased() == lower }) {
dictionaryManager.addWord(word) vocabularyManager.addWord(word)
} }
} }
newWord = "" newWord = ""
} }
} }
struct DictionaryItemView: View { struct VocabularyWordView: View {
let item: DictionaryItem let item: VocabularyWord
let onDelete: () -> Void let onDelete: () -> Void
@State private var isHovered = false @State private var isHovered = false