Skip to content

Commit

Permalink
Merge pull request #203 from scribe-org/feature-188-bugfix
Browse files Browse the repository at this point in the history
#188 #194 autocomplete bug fix and autosuggest placeholders
  • Loading branch information
andrewtavis authored Sep 5, 2022
2 parents aa2fbb6 + c683872 commit f7271ff
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 33 deletions.
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

0 comments on commit f7271ff

Please sign in to comment.