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

#188 #194 autocomplete bug fix and autosuggest placeholders #203

Merged
merged 1 commit into from
Sep 5, 2022
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
6 changes: 5 additions & 1 deletion Keyboards/KeyboardsBase/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ extension String {
return self == self.uppercased()
}

var isCaptalized: Bool {
return self == prefix(1).uppercased() + self.lowercased().dropFirst()
}

func count(of char: Character) -> Int {
return reduce(0) {
$1 == char ? $0 + 1 : $0
}
}

func capitalizingFirstLetter() -> String {
func capitalize() -> String {
return prefix(1).uppercased() + self.lowercased().dropFirst()
}
}
Expand Down
8 changes: 8 additions & 0 deletions Keyboards/KeyboardsBase/InterfaceVariables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,17 @@ enum CommandState {
case invalid
}

/// States of the keyboard corresponding to which auto actions should be presented.
enum AutoActionState {
case complete
case suggest
}

// Baseline state variables.
var keyboardState: KeyboardState = .letters
var shiftButtonState: ShiftButtonState = .normal
var commandState: CommandState = .idle
var autoActionState: AutoActionState = .suggest

// Variables and functions to determine display parameters.
struct DeviceType {
Expand Down Expand Up @@ -269,6 +276,7 @@ func setENKeyboardLayout() {
currencySymbolAlternates = dollarAlternateKeys
spaceBar = "space"
invalidCommandMsg = "Not in Wikidata"
baseAutosuggestions = ["I", "I'm", "we"]

translateKeyLbl = "Translate"
translatePrompt = commandPromptSpacing + "en -› \(getControllerLanguageAbbr()): "
Expand Down
96 changes: 65 additions & 31 deletions Keyboards/KeyboardsBase/KeyboardViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,26 @@ class KeyboardViewController: UIInputViewController {
}
}

/// Hides the partitions for autocomplete and autosuggest.
/// Note: this function is called during command mode when the commandBar is viewable and the Scribe key state.
func hideAutoActionPartitions() {
leftAutoPartition.backgroundColor = .clear
rightAutoPartition.backgroundColor = .clear
}

/// Generates the array for the three autocomplete words.
func getAutocompleteWords() {
completionWords = [" ", " ", " "]
if proxy.documentContextBeforeInput?.count != 0 {
if let inString = proxy.documentContextBeforeInput {
// To only focus on the current word as prefix in autocomplete.
currentPrefix = inString.replacingOccurrences(of: pastStringInTextProxy, with: "")

// Post commands pastStringInTextProxy is "", so take last word.
if currentPrefix.contains(" ") {
currentPrefix = currentPrefix.components(separatedBy: " ").last ?? ""
}

let stringOptions = autocompleteWords.filter { item in
return item.lowercased().hasPrefix(currentPrefix.lowercased())
}
Expand All @@ -215,43 +228,49 @@ class KeyboardViewController: UIInputViewController {
if stringOptions.count <= 3 {
while i < stringOptions.count {
if shiftButtonState == .caps {
// Capital autocomplete if the user starts typing capitalized.
completionWords[i] = stringOptions[i].uppercased()
} else if currentPrefix.isCaptalized {
completionWords[i] = stringOptions[i].capitalize()
} else {
completionWords[i] = currentPrefix == currentPrefix.capitalized ? stringOptions[i].capitalizingFirstLetter() : stringOptions[i]
completionWords[i] = stringOptions[i]
}
i += 1
}
} else {
while i < 3 {
if shiftButtonState == .caps {
// Capital autocomplete if the user starts typing capitalized.
completionWords[i] = stringOptions[i].uppercased()
} else {
completionWords[i] = currentPrefix == currentPrefix.capitalized ? stringOptions[i].capitalizingFirstLetter() : stringOptions[i]
}
i += 1
while i < 3 {
if shiftButtonState == .caps {
completionWords[i] = stringOptions[i].uppercased()
} else if currentPrefix.isCaptalized {
completionWords[i] = stringOptions[i].capitalize()
} else {
completionWords[i] = stringOptions[i]
}
i += 1
}
}
} else {
getDefaultAutoCompleteWords(autocompleteWords)
getDefaultAutoSuggestions()
}
} else {
// For getting words on launch. When the user has not typed anything in the proxy.
getDefaultAutoCompleteWords(autocompleteWords)
// For getting words on launch when the user hasn't typed anything in the proxy.
getDefaultAutoSuggestions()
}
}

/// Suggests words on launch before the user starts typing.
/// Note: replace this section when we add the most common used words.
func getDefaultAutoCompleteWords(_ keys: [String]) {
func getDefaultAutoSuggestions() {
var i = 0
var threeWords = [String]()
completionWords = [String]()
while i < 3 {
threeWords.append(keys[i])
i += 1
if shiftButtonState == .shift {
completionWords.append(baseAutosuggestions[i].capitalize())
} else if shiftButtonState == .caps {
completionWords.append(baseAutosuggestions[i].uppercased())
} else {
completionWords.append(baseAutosuggestions[i])
}
i += 1
}
completionWords = threeWords
}

/// Clears the text proxy when inserting using an auto action.
Expand Down Expand Up @@ -287,13 +306,6 @@ class KeyboardViewController: UIInputViewController {
}
}

/// Hides the partitions for autocomplete and autosuggest.
/// Note: this function is called during command mode when the commandBar is viewable and the Scribe key state.
func hideAutoActionPartitions() {
leftAutoPartition.backgroundColor = .clear
rightAutoPartition.backgroundColor = .clear
}

// The background for the Scribe command elements.
@IBOutlet var commandBackground: UILabel!
func setCommandBackground() {
Expand Down Expand Up @@ -365,7 +377,11 @@ class KeyboardViewController: UIInputViewController {

/// Sets up command buttons to execute autocomplete and autosuggest.
func conditionallySetAutoActionBtns() {
getAutocompleteWords()
if autoActionState == .suggest {
getDefaultAutoSuggestions()
} else {
getAutocompleteWords()
}
if commandState == .idle {
deactivateBtn(btn: translateKey)
deactivateBtn(btn: conjugateKey)
Expand Down Expand Up @@ -951,7 +967,10 @@ class KeyboardViewController: UIInputViewController {

commandBar.text = ""
commandBar.hide()
conditionallySetAutoActionBtns()
// Set autosuggestions on keyboard's first load.
if keyboardLoad == true {
conditionallySetAutoActionBtns()
}
}
}

Expand Down Expand Up @@ -1212,9 +1231,6 @@ class KeyboardViewController: UIInputViewController {
doubleSpacePeriodPossible = false
}

// Reset the Russian verbs view after a selection.
ruConjugationState = .present

switch originalKey {
case "Scribe":
if proxy.selectedText != nil && [.idle, .select, .alreadyPlural, .invalid].contains(commandState) { // annotate word
Expand Down Expand Up @@ -1313,45 +1329,56 @@ class KeyboardViewController: UIInputViewController {

case "firstPersonSingular":
returnConjugation(keyPressed: sender, requestedTense: tenseFPS)
autoActionState = .suggest
loadKeys()

case "secondPersonSingular":
returnConjugation(keyPressed: sender, requestedTense: tenseSPS)
autoActionState = .suggest
loadKeys()

case "thirdPersonSingular":
returnConjugation(keyPressed: sender, requestedTense: tenseTPS)
autoActionState = .suggest
loadKeys()

case "firstPersonPlural":
returnConjugation(keyPressed: sender, requestedTense: tenseFPP)
autoActionState = .suggest
loadKeys()

case "secondPersonPlural":
returnConjugation(keyPressed: sender, requestedTense: tenseSPP)
autoActionState = .suggest
loadKeys()

case "thirdPersonPlural":
returnConjugation(keyPressed: sender, requestedTense: tenseTPP)
autoActionState = .suggest
loadKeys()

case "conjugateTopLeft":
returnConjugation(keyPressed: sender, requestedTense: tenseTopLeft)
autoActionState = .suggest
loadKeys()

case "conjugateTopRight":
returnConjugation(keyPressed: sender, requestedTense: tenseTopRight)
autoActionState = .suggest
loadKeys()

case "conjugateBottomLeft":
returnConjugation(keyPressed: sender, requestedTense: tenseBottomLeft)
autoActionState = .suggest
loadKeys()

case "conjugateBottomRight":
returnConjugation(keyPressed: sender, requestedTense: tenseBottomRight)
autoActionState = .suggest
loadKeys()

case "AutoAction1":
autoActionState = .suggest
clearPrefixFromTextFieldProxy()
proxy.insertText(translateKey.titleLabel?.text ?? "")
proxy.insertText(" ")
Expand All @@ -1374,6 +1401,7 @@ class KeyboardViewController: UIInputViewController {
nounAnnotationsToDisplay = 0

case "AutoAction2":
autoActionState = .suggest
clearPrefixFromTextFieldProxy()
proxy.insertText(conjugateKey.titleLabel?.text ?? "")
proxy.insertText(" ")
Expand All @@ -1396,6 +1424,7 @@ class KeyboardViewController: UIInputViewController {
nounAnnotationsToDisplay = 0

case "AutoAction3":
autoActionState = .suggest
clearPrefixFromTextFieldProxy()
proxy.insertText(pluralKey.titleLabel?.text ?? "")
proxy.insertText(" ")
Expand Down Expand Up @@ -1443,10 +1472,12 @@ class KeyboardViewController: UIInputViewController {
clearCommandBar()

// Inserting the placeholder when commandBar text is deleted.
autoActionState = .complete
commandBar.conditionallyAddPlaceholder()
conditionallySetAutoActionBtns()

case spaceBar:
autoActionState = .suggest
commandBar.conditionallyRemovePlaceholder()
if ![.translate, .conjugate, .plural].contains(commandState) {
proxy.insertText(" ")
Expand Down Expand Up @@ -1537,6 +1568,7 @@ class KeyboardViewController: UIInputViewController {
commandBar.textColor = keyCharColor
return
} else if [.translate, .plural].contains(commandState) { // functional commands above
autoActionState = .suggest
commandState = .idle
clearCommandBar()
autoCapAtStartOfProxy()
Expand Down Expand Up @@ -1596,6 +1628,7 @@ class KeyboardViewController: UIInputViewController {
capsLockPossible = true

default:
autoActionState = .complete
commandBar.conditionallyRemovePlaceholder()
if shiftButtonState == .shift {
shiftButtonState = .normal
Expand Down Expand Up @@ -1664,6 +1697,7 @@ class KeyboardViewController: UIInputViewController {
shiftButtonState = .caps
loadKeys()
clearCommandBar()
conditionallySetAutoActionBtns()
}

// To make sure that the user can still use the double space period shortcut after numbers and symbols.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ let prepositions = loadJSONToDict(filename: "prepositions")
// Words that should not be included in autocomplete should be added to the string below.
let autocompleteWords = nouns!.keys.filter(
{ $0.rangeOfCharacter(from: CharacterSet(charactersIn: "1234567890-")) == nil }
).sorted()
).sorted{$0.caseInsensitiveCompare($1) == .orderedAscending}
var baseAutosuggestions = [String]()

var currentPrefix: String = ""
var pastStringInTextProxy: String = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func setFRKeyboardLayout() {
currencySymbolAlternates = euroAlternateKeys
spaceBar = "espace"
invalidCommandMsg = "Pas dans Wikidata"
baseAutosuggestions = ["je", "il", "le"]

translateKeyLbl = "Traduire"
translatePlaceholder = "Entrez un mot"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func setDEKeyboardLayout() {
currencySymbolAlternates = euroAlternateKeys
spaceBar = "Leerzeichen"
invalidCommandMsg = "Nicht in Wikidata"
baseAutosuggestions = ["ich", "die", "das"]

translateKeyLbl = "Übersetzen"
translatePlaceholder = "Wort eingeben"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func setITKeyboardLayout() {
currencySymbolAlternates = euroAlternateKeys
spaceBar = "spazio"
invalidCommandMsg = "Non in Wikidata"
baseAutosuggestions = ["ho", "non", "ma"]

translateKeyLbl = "Tradurre"
translatePlaceholder = "Inserisci una parola"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func setPTKeyboardLayout() {
currencySymbolAlternates = dollarAlternateKeys
spaceBar = "espaço"
invalidCommandMsg = "Não está no Wikidata"
baseAutosuggestions = ["o", "a", "eu"]

translateKeyLbl = "Traduzir"
translatePlaceholder = "Digite uma palavra"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func setRUKeyboardLayout() {
currencySymbolAlternates = roubleAlternateKeys
spaceBar = "Пробел"
invalidCommandMsg = "Нет в Викиданных"
baseAutosuggestions = ["я", "а", "в"]

translateKeyLbl = "Перевести"
translatePlaceholder = "Введите слово"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func setESKeyboardLayout() {
currencySymbolAlternates = dollarAlternateKeys
spaceBar = "espacio"
invalidCommandMsg = "No en Wikidata"
baseAutosuggestions = ["el", "la", "no"]

translateKeyLbl = "Traducir"
translatePlaceholder = "Ingrese una palabra"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func setSVKeyboardLayout() {
currencySymbolAlternates = kronaAlternateKeys
spaceBar = "mellanslag"
invalidCommandMsg = "Inte i Wikidata"
baseAutosuggestions = ["jag", "det", "men"]

translateKeyLbl = "Översätt"
translatePlaceholder = "Ange ett ord"
Expand Down