mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-24 00:27:40 +00:00
can now download a lexical model from the cloud
This commit is contained in:
parent
641f3c271a
commit
0828049385
3 changed files with 272 additions and 25 deletions
|
|
@ -0,0 +1,208 @@
|
|||
//
|
||||
// LanguageLMDetailViewController.swift
|
||||
// KeymanEngine
|
||||
//
|
||||
// Created by Randy Boring on 7/19/19.
|
||||
// Copyright © 2019 SIL International. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
import UIKit
|
||||
|
||||
private let toolbarButtonTag = 100
|
||||
private let toolbarLabelTag = 101
|
||||
private let toolbarActivityIndicatorTag = 102
|
||||
|
||||
class LanguageLMDetailViewController: UITableViewController, UIAlertViewDelegate {
|
||||
private var userLexicalModels: [String: InstallableLexicalModel] = [:]
|
||||
private var isUpdate = false
|
||||
private let language: Language
|
||||
public var lexicalModels: [LexicalModel]? = nil
|
||||
|
||||
private var lexicalModelDownloadStartedObserver: NotificationObserver?
|
||||
private var lexicalModelDownloadFailedObserver: NotificationObserver?
|
||||
|
||||
init(language: Language) {
|
||||
self.language = language
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
super.loadView()
|
||||
loadUserLexicalModels()
|
||||
tableView.dataSource = self
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
lexicalModelDownloadStartedObserver = NotificationCenter.default.addObserver(
|
||||
forName: Notifications.lexicalModelDownloadStarted,
|
||||
observer: self,
|
||||
function: LanguageLMDetailViewController.lexicalModelDownloadStarted)
|
||||
lexicalModelDownloadFailedObserver = NotificationCenter.default.addObserver(
|
||||
forName: Notifications.lexicalModelDownloadFailed,
|
||||
observer: self,
|
||||
function: LanguageLMDetailViewController.lexicalModelDownloadFailed)
|
||||
log.info("viewDidLoad: LanguageLMDetailViewController (registered for lexicalModelDownloadStarted)")
|
||||
}
|
||||
|
||||
override open func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
log.info("didAppear: LanguageLMDetailViewController (actually willAppear)")
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
log.info("didAppear: LanguageLMDetailViewController")
|
||||
|
||||
navigationController?.setToolbarHidden(true, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Table view data source UITableViewDataSource
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return lexicalModels!.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cellIdentifier = "Cell"
|
||||
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) {
|
||||
return cell
|
||||
}
|
||||
|
||||
let cell = KeyboardNameTableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
|
||||
let selectionColor = UIView()
|
||||
selectionColor.backgroundColor = UIColor(red: 204.0 / 255.0, green: 136.0 / 255.0, blue: 34.0 / 255.0, alpha: 1.0)
|
||||
cell.selectedBackgroundView = selectionColor
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
|
||||
let lexicalModel = lexicalModels![indexPath.section]
|
||||
let cell = cell as! KeyboardNameTableViewCell
|
||||
cell.indexPath = indexPath
|
||||
cell.textLabel?.text = lexicalModel.name
|
||||
if isAdded(languageID: language.id, lexicalModelID: lexicalModel.id) {
|
||||
cell.accessoryType = .checkmark
|
||||
cell.isUserInteractionEnabled = false
|
||||
cell.textLabel?.isEnabled = false
|
||||
cell.detailTextLabel?.isEnabled = false
|
||||
} else {
|
||||
cell.accessoryType = .none
|
||||
cell.isUserInteractionEnabled = true
|
||||
cell.textLabel?.isEnabled = true
|
||||
cell.detailTextLabel?.isEnabled = true
|
||||
}
|
||||
|
||||
let kbState = Manager.shared.stateForLexicalModel(withID: lexicalModel.id)
|
||||
cell.setKeyboardState(kbState, selected: false, defaultAccessoryType: cell.accessoryType)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.cellForRow(at: indexPath)?.isSelected = false
|
||||
let lexicalModelIndex = indexPath.section
|
||||
let lexicalModel = lexicalModels![lexicalModelIndex]
|
||||
|
||||
let state = Manager.shared.stateForLexicalModel(withID: lexicalModel.id)
|
||||
if state != .downloading {
|
||||
if state == .needsDownload {
|
||||
isUpdate = false
|
||||
} else {
|
||||
isUpdate = true
|
||||
}
|
||||
|
||||
let alertController = UIAlertController(title: "\(language.name): \(lexicalModel.name)",
|
||||
message: "Would you like to download this dictionary?",
|
||||
preferredStyle: UIAlertControllerStyle.alert)
|
||||
alertController.addAction(UIAlertAction(title: "Cancel",
|
||||
style: UIAlertActionStyle.cancel,
|
||||
handler: nil))
|
||||
alertController.addAction(UIAlertAction(title: "Download",
|
||||
style: UIAlertActionStyle.default,
|
||||
handler: {_ in self.downloadHandler(lexicalModelIndex)} ))
|
||||
|
||||
self.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func downloadHandler(_ lexicalModelIndex: Int) {
|
||||
// Manager.shared.downloadLexicalModel(withID: lexicalModels![lexicalModelIndex].id,
|
||||
// languageID: language.id, isUpdate: isUpdate)
|
||||
Manager.shared.downloadLexicalModelPackage(string: (lexicalModels?[lexicalModelIndex].packageFilename)!)
|
||||
/*
|
||||
if let packageURL = URLComponents(string: (lexicalModels?[lexicalModelIndex].packageFilename)!) {
|
||||
Manager.shared.downloadLexicalModel(from: packageURL.url!)
|
||||
} else {
|
||||
log.error("couldn't make url to download \(lexicalModels?[lexicalModelIndex].packageFilename)")
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private func lexicalModelDownloadStarted() {
|
||||
log.info("lexicalModelDownloadStarted: LanguageLMDetailViewController")
|
||||
view.isUserInteractionEnabled = false
|
||||
navigationItem.setHidesBackButton(true, animated: true)
|
||||
|
||||
let toolbarFrame = navigationController!.toolbar.frame
|
||||
let labelFrame = CGRect(origin: toolbarFrame.origin,
|
||||
size: CGSize(width: toolbarFrame.width * 0.95, height: toolbarFrame.height * 0.7))
|
||||
let label = UILabel(frame: labelFrame)
|
||||
label.backgroundColor = UIColor.clear
|
||||
label.textColor = UIColor.white
|
||||
label.textAlignment = .center
|
||||
label.center = CGPoint(x: toolbarFrame.width * 0.5, y: toolbarFrame.height * 0.5)
|
||||
label.text = "Downloading\u{2026}"
|
||||
label.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin,
|
||||
.flexibleBottomMargin, .flexibleWidth, .flexibleHeight]
|
||||
label.tag = toolbarLabelTag
|
||||
|
||||
let indicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
indicatorView.center = CGPoint(x: toolbarFrame.width - indicatorView.frame.width,
|
||||
y: toolbarFrame.height * 0.5)
|
||||
indicatorView.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleBottomMargin]
|
||||
indicatorView.tag = toolbarActivityIndicatorTag
|
||||
indicatorView.startAnimating()
|
||||
|
||||
navigationController?.toolbar.viewWithTag(toolbarButtonTag)?.removeFromSuperview()
|
||||
navigationController?.toolbar.viewWithTag(toolbarLabelTag)?.removeFromSuperview()
|
||||
navigationController?.toolbar.viewWithTag(toolbarActivityIndicatorTag)?.removeFromSuperview()
|
||||
navigationController?.toolbar.addSubview(label)
|
||||
navigationController?.toolbar.addSubview(indicatorView)
|
||||
navigationController?.setToolbarHidden(false, animated: true)
|
||||
}
|
||||
|
||||
private func lexicalModelDownloadFailed() {
|
||||
log.info("lexicalModelDownloadFailed: LanguageLMDetailViewController")
|
||||
view.isUserInteractionEnabled = true
|
||||
navigationItem.setHidesBackButton(false, animated: true)
|
||||
}
|
||||
|
||||
private func loadUserLexicalModels() {
|
||||
guard let userLmList = Storage.active.userDefaults.userLexicalModels, !userLmList.isEmpty else {
|
||||
userLexicalModels = [:]
|
||||
return
|
||||
}
|
||||
|
||||
userLexicalModels = [:]
|
||||
for lm in userLmList {
|
||||
let dictKey = "\(lm.languageID)_\(lm.id)"
|
||||
userLexicalModels[dictKey] = lm
|
||||
}
|
||||
}
|
||||
|
||||
private func isAdded(languageID: String?, lexicalModelID: String?) -> Bool {
|
||||
guard let languageID = languageID, let lexicalModelID = lexicalModelID else {
|
||||
return false
|
||||
}
|
||||
return userLexicalModels["\(languageID)_\(lexicalModelID)"] != nil
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LanguageLMDetailViewController" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableView opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" bouncesZoom="NO" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="i5M-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="vLr-E1-eTs"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="Tng-2m-Rnh"/>
|
||||
<outlet property="delegate" destination="-1" id="9aC-8N-iBw"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -15,7 +15,7 @@ private let toolbarActivityIndicatorTag = 102
|
|||
|
||||
class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelegate {
|
||||
private var userLexicalModels: [InstallableLexicalModel] = [InstallableLexicalModel]()
|
||||
public var language: Language? = nil
|
||||
public var language: Language!
|
||||
private var updateQueue: [InstallableLexicalModel]?
|
||||
private var _isDoneButtonEnabled = false
|
||||
private var isDidUpdateCheck = false
|
||||
|
|
@ -24,17 +24,19 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
private var lexicalModelDownloadCompletedObserver: NotificationObserver?
|
||||
private var lexicalModelDownloadFailedObserver: NotificationObserver?
|
||||
|
||||
public init(_ language: Language) {
|
||||
self.language = language
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let langName = language?.name {
|
||||
title = "\(langName) Lexical Models"
|
||||
} else {
|
||||
title = "Lexical Models"
|
||||
}
|
||||
if language == nil {
|
||||
setIsDoneButtonEnabled(false)
|
||||
}
|
||||
title = "\(language.name) Dictionaries"
|
||||
isDidUpdateCheck = false
|
||||
updateQueue = nil
|
||||
if Manager.shared.canAddNewLexicalModels {
|
||||
|
|
@ -137,9 +139,6 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
if Manager.shared.removeLexicalModel(at: globalIndex) {
|
||||
loadUserLexicalModels()
|
||||
}
|
||||
if language == nil {
|
||||
setIsDoneButtonEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView,
|
||||
|
|
@ -148,9 +147,6 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
}
|
||||
|
||||
func showLexicalModelInfoView(with index: Int) {
|
||||
if language == nil {
|
||||
setIsDoneButtonEnabled(true)
|
||||
}
|
||||
let lm = userLexicalModels[index]
|
||||
let version = lm.version
|
||||
|
||||
|
|
@ -238,14 +234,14 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
}
|
||||
updateQueue = nil
|
||||
let label = navigationController?.toolbar?.viewWithTag(toolbarLabelTag) as? UILabel
|
||||
label?.text = "Lexical models successfully updated!"
|
||||
label?.text = "Dictionaries successfully updated!"
|
||||
navigationController?.toolbar?.viewWithTag(toolbarActivityIndicatorTag)?.removeFromSuperview()
|
||||
Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.hideToolbarDelayed),
|
||||
userInfo: nil, repeats: false)
|
||||
}
|
||||
} else {
|
||||
let label = navigationController?.toolbar?.viewWithTag(toolbarLabelTag) as? UILabel
|
||||
label?.text = "Lexical model successfully downloaded!"
|
||||
label?.text = "Dictionary successfully downloaded!"
|
||||
navigationController?.toolbar?.viewWithTag(toolbarActivityIndicatorTag)?.removeFromSuperview()
|
||||
Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.hideToolbarDelayed),
|
||||
userInfo: nil, repeats: false)
|
||||
|
|
@ -276,9 +272,9 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
let title: String
|
||||
if view == navigationController?.topViewController?.view {
|
||||
updateQueue = nil
|
||||
title = "Lexical model Update Error"
|
||||
title = "Dictionary Update Error"
|
||||
} else {
|
||||
title = "Lexical model Download Error"
|
||||
title = "Dictionary Download Error"
|
||||
}
|
||||
navigationController?.setToolbarHidden(true, animated: true)
|
||||
|
||||
|
|
@ -421,13 +417,30 @@ class LexicalModelPickerViewController: UITableViewController, UIAlertViewDelega
|
|||
}
|
||||
|
||||
func showAddLexicalModel() {
|
||||
let button: UIButton? = (navigationController?.toolbar?.viewWithTag(toolbarButtonTag) as? UIButton)
|
||||
button?.isEnabled = false
|
||||
let vc = LanguageViewController(Manager.shared.apiLexicalModelRepository) //may need to be different for models
|
||||
navigationController?.pushViewController(vc, animated: true)
|
||||
if language == nil {
|
||||
setIsDoneButtonEnabled(true)
|
||||
//get list of lexical models for this languageID and show it
|
||||
func listCompletionHandler(lexicalModels: [LexicalModel]?, error: Error?) -> Void {
|
||||
if let error = error {
|
||||
log.info("Failed to fetch lexical model list for "+language.id+". error: "+(error as! String))
|
||||
self.lexicalModelDownloadFailed(LexicalModelDownloadFailedNotification(lmOrLanguageID: language.id, error: error))
|
||||
} else if nil == lexicalModels {
|
||||
log.info("No lexical models available for language \(language.id) (nil)")
|
||||
} else if 0 == lexicalModels?.count {
|
||||
log.info("No lexical models available for language \(language.id) (empty)")
|
||||
} else {
|
||||
log.info("Fetched lexical model list for "+language.id+".")
|
||||
// show the list of lexical models (on the main thread)
|
||||
DispatchQueue.main.async {
|
||||
let button: UIButton? = (self.navigationController?.toolbar?.viewWithTag(toolbarButtonTag) as? UIButton)
|
||||
button?.isEnabled = false
|
||||
let vc = LanguageLMDetailViewController(language: self.language)
|
||||
vc.lexicalModels = lexicalModels!
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Manager.shared.apiLexicalModelRepository.fetchList(languageID: language.id, completionHandler: listCompletionHandler)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue