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

Add a code load status snackbar for iOS frontend #1530

Merged
merged 1 commit into from
Sep 29, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.flowOf
import platform.Foundation.NSLog
import platform.Foundation.NSOperationQueue
import platform.Foundation.NSURLSession

class EmojiSearchLauncher(
Expand All @@ -40,7 +41,7 @@ class EmojiSearchLauncher(
private val manifestUrl = "http://localhost:8080/manifest.zipline.json"

@Suppress("unused") // Invoked in Swift.
fun createTreehouseApp(): TreehouseApp<EmojiSearchPresenter> {
fun createTreehouseApp(listener: EmojiSearchEventListener): TreehouseApp<EmojiSearchPresenter> {
val ziplineHttpClient = nsurlSession.asZiplineHttpClient()

val treehouseAppFactory = TreehouseAppFactory(
Expand All @@ -49,10 +50,16 @@ class EmojiSearchLauncher(
eventListener = object : EventListener() {
override fun codeLoadFailed(app: TreehouseApp<*>, manifestUrl: String?, exception: Exception, startValue: Any?) {
NSLog("Treehouse: codeLoadFailed: $exception")
NSOperationQueue.mainQueue.addOperationWithBlock {
listener.codeLoadFailed()
}
}

override fun codeLoadSuccess(app: TreehouseApp<*>, manifestUrl: String?, manifest: ZiplineManifest, zipline: Zipline, startValue: Any?) {
NSLog("Treehouse: codeLoadSuccess")
NSOperationQueue.mainQueue.addOperationWithBlock {
listener.codeLoadSuccess()
}
}
},
)
Expand All @@ -73,3 +80,8 @@ class EmojiSearchLauncher(
return treehouseApp
}
}

interface EmojiSearchEventListener {
fun codeLoadFailed()
fun codeLoadSuccess()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 52;
objects = {

/* Begin PBXBuildFile section */
Expand All @@ -16,6 +16,7 @@
AACC042628AC72AC00721342 /* RemoteImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AACC042528AC72AC00721342 /* RemoteImageLoader.swift */; };
C2F7CE6628BEAB6C00A66A69 /* ImageBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F7CE6528BEAB6C00A66A69 /* ImageBinding.swift */; };
C2F7FBA228BEB54200A66A69 /* TextInputBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F7FBA128BEB54200A66A69 /* TextInputBinding.swift */; };
CB5D6B092AC5326B004BF9CB /* SnackBar in Frameworks */ = {isa = PBXBuildFile; productRef = CB5D6B082AC5326B004BF9CB /* SnackBar */; };
CB85C0B725AFE61A007A2CC7 /* EmojiSearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB85C0B625AFE61A007A2CC7 /* EmojiSearchViewController.swift */; };
CB9F76562810A8A8008CF457 /* IosHostApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB9F76552810A8A8008CF457 /* IosHostApi.swift */; };
/* End PBXBuildFile section */
Expand All @@ -42,6 +43,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CB5D6B092AC5326B004BF9CB /* SnackBar in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -101,6 +103,9 @@
dependencies = (
);
name = EmojiSearchApp;
packageProductDependencies = (
CB5D6B082AC5326B004BF9CB /* SnackBar */,
);
productName = EmojiSearchApp;
productReference = 635661D121F12B7E00DD7240 /* EmojiSearchApp.app */;
productType = "com.apple.product-type.application";
Expand Down Expand Up @@ -130,6 +135,9 @@
Base,
);
mainGroup = 635661C821F12B7D00DD7240;
packageReferences = (
CB5D6B072AC5326B004BF9CB /* XCRemoteSwiftPackageReference "SnackBar" */,
);
productRefGroup = 635661D221F12B7E00DD7240 /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -415,6 +423,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
CB5D6B072AC5326B004BF9CB /* XCRemoteSwiftPackageReference "SnackBar" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ahmedAlmasri/SnackBar.swift";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.1.2;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
CB5D6B082AC5326B004BF9CB /* SnackBar */ = {
isa = XCSwiftPackageProductDependency;
package = CB5D6B072AC5326B004BF9CB /* XCRemoteSwiftPackageReference "SnackBar" */;
productName = SnackBar;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 635661C921F12B7D00DD7240 /* Project object */;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import Foundation
import UIKit
import EmojiSearchKt
import SnackBar

class EmojiSearchViewController : UIViewController {

class EmojiSearchViewController : UIViewController, EmojiSearchEventListener {
// MARK: - Private Properties

private let urlSession: URLSession = .init(configuration: .default)
private var success = true
private var snackBar: SnackBarPresentable? = nil

// MARK: - UIViewController

Expand All @@ -34,7 +36,7 @@ class EmojiSearchViewController : UIViewController {

override func loadView() {
let emojiSearchLauncher = EmojiSearchLauncher(nsurlSession: urlSession, hostApi: IosHostApi())
let treehouseApp = emojiSearchLauncher.createTreehouseApp()
let treehouseApp = emojiSearchLauncher.createTreehouseApp(listener: self)
let widgetSystem = EmojiSearchWidgetSystem(treehouseApp: treehouseApp)
let treehouseView = TreehouseUIView(widgetSystem: widgetSystem)
let content = treehouseApp.createContent(
Expand All @@ -44,6 +46,29 @@ class EmojiSearchViewController : UIViewController {
ExposedKt.bindWhenReady(content: content, view: treehouseView)
view = treehouseView.view
}

func codeLoadFailed() {
if (success) {
// Only show the Snackbar on the first transition from success.
success = false
let snackBar = SnackBar.make(in: view, message: "Unable to load guest code from server", duration: SnackBar.Duration.infinite)
.setAction(with: "Dismiss", action: { self.maybeDismissSnackBar() })
snackBar.show()
self.snackBar = snackBar
}
}

func codeLoadSuccess() {
success = true
maybeDismissSnackBar()
}

private func maybeDismissSnackBar() {
if let snackBar = snackBar {
snackBar.dismiss()
self.snackBar = nil
}
}
}

class EmojiSearchContent : TreehouseContentSource {
Expand Down