mirror of
https://github.com/jeremysrand/ListenerApp.git
synced 2024-11-29 06:50:12 +00:00
Add an initial help screen that is visible on iPad and macOS.
This commit is contained in:
parent
d7c430f588
commit
a9b0af4fca
@ -16,6 +16,12 @@
|
||||
9D2A6D2327E236E400DF3D85 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564E26A36B410075EBC7 /* ytcpsocket.c */; };
|
||||
9D2A6D2427E236FD00DF3D85 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564D26A36B410075EBC7 /* yudpsocket.c */; };
|
||||
9D2A6D2727E24BD600DF3D85 /* SpeechForwarderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2627E24BD600DF3D85 /* SpeechForwarderMock.swift */; };
|
||||
9D2A6D2927E2A5E700DF3D85 /* ListenerInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2827E2A5E700DF3D85 /* ListenerInfoView.swift */; };
|
||||
9D2A6D3027E2AA6200DF3D85 /* RichTextExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2B27E2AA6200DF3D85 /* RichTextExtension.swift */; };
|
||||
9D2A6D3127E2AA6200DF3D85 /* RichTextEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2C27E2AA6200DF3D85 /* RichTextEnums.swift */; };
|
||||
9D2A6D3227E2AA6200DF3D85 /* Webview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2D27E2AA6200DF3D85 /* Webview.swift */; };
|
||||
9D2A6D3327E2AA6200DF3D85 /* ColorSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2E27E2AA6200DF3D85 /* ColorSet.swift */; };
|
||||
9D2A6D3427E2AA6200DF3D85 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D2A6D2F27E2AA6200DF3D85 /* RichText.swift */; };
|
||||
9D5155F326A1EF7B0075EBC7 /* ListenerGSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D5155F226A1EF7B0075EBC7 /* ListenerGSApp.swift */; };
|
||||
9D5155F726A1EF7C0075EBC7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */; };
|
||||
9D5155FA26A1EF7C0075EBC7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9D5155F926A1EF7C0075EBC7 /* Preview Assets.xcassets */; };
|
||||
@ -61,6 +67,12 @@
|
||||
9D0DC15826F2E47A007EB92D /* ListenerGS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ListenerGS.entitlements; sourceTree = "<group>"; };
|
||||
9D2A6D1D27E235E400DF3D85 /* GSServerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GSServerMock.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2627E24BD600DF3D85 /* SpeechForwarderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeechForwarderMock.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2827E2A5E700DF3D85 /* ListenerInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenerInfoView.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2B27E2AA6200DF3D85 /* RichTextExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichTextExtension.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2C27E2AA6200DF3D85 /* RichTextEnums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichTextEnums.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2D27E2AA6200DF3D85 /* Webview.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Webview.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2E27E2AA6200DF3D85 /* ColorSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorSet.swift; sourceTree = "<group>"; };
|
||||
9D2A6D2F27E2AA6200DF3D85 /* RichText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichText.swift; sourceTree = "<group>"; };
|
||||
9D5155EF26A1EF7B0075EBC7 /* ListenerGS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ListenerGS.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9D5155F226A1EF7B0075EBC7 /* ListenerGSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenerGSApp.swift; sourceTree = "<group>"; };
|
||||
9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
@ -120,6 +132,18 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
9D2A6D2A27E2AA6200DF3D85 /* RichText */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9D2A6D2B27E2AA6200DF3D85 /* RichTextExtension.swift */,
|
||||
9D2A6D2C27E2AA6200DF3D85 /* RichTextEnums.swift */,
|
||||
9D2A6D2D27E2AA6200DF3D85 /* Webview.swift */,
|
||||
9D2A6D2E27E2AA6200DF3D85 /* ColorSet.swift */,
|
||||
9D2A6D2F27E2AA6200DF3D85 /* RichText.swift */,
|
||||
);
|
||||
path = RichText;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9D5155E626A1EF7B0075EBC7 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -149,12 +173,14 @@
|
||||
9D0DC15826F2E47A007EB92D /* ListenerGS.entitlements */,
|
||||
9D5155F226A1EF7B0075EBC7 /* ListenerGSApp.swift */,
|
||||
9D6F27082728EF410089585E /* MainView.swift */,
|
||||
9D2A6D2827E2A5E700DF3D85 /* ListenerInfoView.swift */,
|
||||
9DD67CEF2728F5B700243FC6 /* DestinationsView.swift */,
|
||||
9DCCDACB271FB87100F311DF /* GSDestinations.swift */,
|
||||
9DD8905F2772D3B20084A894 /* GSView.swift */,
|
||||
9D6ED239271E6BD600D773CD /* SpeechForwarder.swift */,
|
||||
9D05BAA927DFDE6300D9CC4B /* GSConnection.swift */,
|
||||
9DD8905E27726C140084A894 /* ListenerGS Icon.pxm */,
|
||||
9D2A6D2A27E2AA6200DF3D85 /* RichText */,
|
||||
9D51566326A36F530075EBC7 /* BinUtils */,
|
||||
9D51563626A36AD60075EBC7 /* SwiftSocket */,
|
||||
9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */,
|
||||
@ -379,17 +405,23 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9D2A6D3127E2AA6200DF3D85 /* RichTextEnums.swift in Sources */,
|
||||
9D51565726A36B410075EBC7 /* TCPClient.swift in Sources */,
|
||||
9D05BAAA27DFDE6300D9CC4B /* GSConnection.swift in Sources */,
|
||||
9D2A6D3227E2AA6200DF3D85 /* Webview.swift in Sources */,
|
||||
9D6F27092728EF410089585E /* MainView.swift in Sources */,
|
||||
9D51565526A36B410075EBC7 /* UDPClient.swift in Sources */,
|
||||
9DD67CF02728F5B700243FC6 /* DestinationsView.swift in Sources */,
|
||||
9D51565626A36B410075EBC7 /* Socket.swift in Sources */,
|
||||
9D2A6D3427E2AA6200DF3D85 /* RichText.swift in Sources */,
|
||||
9D2A6D3327E2AA6200DF3D85 /* ColorSet.swift in Sources */,
|
||||
9D51565326A36B410075EBC7 /* yudpsocket.c in Sources */,
|
||||
9DD890602772D3B20084A894 /* GSView.swift in Sources */,
|
||||
9D51565226A36B410075EBC7 /* Result.swift in Sources */,
|
||||
9D6ED23A271E6BD600D773CD /* SpeechForwarder.swift in Sources */,
|
||||
9D2A6D3027E2AA6200DF3D85 /* RichTextExtension.swift in Sources */,
|
||||
9D5155F326A1EF7B0075EBC7 /* ListenerGSApp.swift in Sources */,
|
||||
9D2A6D2927E2A5E700DF3D85 /* ListenerInfoView.swift in Sources */,
|
||||
9D51566526A36F6D0075EBC7 /* BinUtils.swift in Sources */,
|
||||
9DCCDACC271FB87100F311DF /* GSDestinations.swift in Sources */,
|
||||
9D51565426A36B410075EBC7 /* ytcpsocket.c in Sources */,
|
||||
|
@ -19,7 +19,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>548</string>
|
||||
<string>598</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
60
ListenerGS/ListenerInfoView.swift
Normal file
60
ListenerGS/ListenerInfoView.swift
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// ListenerInfoView.swift
|
||||
// ListenerGS
|
||||
//
|
||||
// Created by Jeremy Rand on 2022-03-16.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ListenerInfoView: View {
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
RichText(html:
|
||||
"""
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<p>
|
||||
ListenerGS allows you to use your modern device as a speech recognition peripheral for a network capable
|
||||
Apple IIGS. For more information about how to use the app and links to the software you need to download
|
||||
to your GS, please visit <a href="https://www.rand-emonium.com/listenergs/">https://www.rand-emonium.com/listenergs/</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you have the software installed and configured on your Apple IIGS, you should launch an desktop application
|
||||
that accepts text. The Teach application is an example of an application that would work. Make sure there is a
|
||||
window open which you can type into and then open the Listener NDA from under the Apple menu. The Listener NDA window
|
||||
will say it is waiting for a connection.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In this app, tap the "+" button and enter the IP address or hostname of your Apple IIGS. You can enter multiple IP
|
||||
addresses and hostnames if you have multiple machines. Your destinations are synced through iCloud so if you have
|
||||
multiple modern devices, you should find the IP addresses are mirrored to those other devices.
|
||||
</p>
|
||||
|
||||
<p>Select one of these destinations and tap the "Connect" button to bring up a network connection to your Apple IIGS.
|
||||
On the GS, you should find the NDA window also indicates that the connection is up. Then tap the "Listen and Send Text"
|
||||
button. Speak clearly and you should find that your words are typed into the window on your GS. If the NDA window was
|
||||
top-most when you started speaking, you should find that it goes to the back.</p>
|
||||
|
||||
<p>
|
||||
Top "Stop Listening" when you want to stop entering text through speech and "Disconnect" when you are done using the app.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
// .frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.navigationBarTitle("Welcome to ListenerGS!")
|
||||
}
|
||||
}
|
||||
|
||||
struct ListenerInfoView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ListenerInfoView()
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ struct MainView: View {
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
DestinationsView()
|
||||
EmptyView() // JSR_TODO - Maybe display some instructions here.
|
||||
ListenerInfoView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
18
ListenerGS/RichText/ColorSet.swift
Normal file
18
ListenerGS/RichText/ColorSet.swift
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// ColorSet.swift
|
||||
//
|
||||
//
|
||||
// Created by 이웅재(NuPlay) on 2022/01/04.
|
||||
// https://github.com/NuPlay/RichText
|
||||
|
||||
import SwiftUI
|
||||
|
||||
public struct ColorSet {
|
||||
var light: String
|
||||
var dark: String
|
||||
|
||||
public init(light: String, dark: String) {
|
||||
self.light = light
|
||||
self.dark = dark
|
||||
}
|
||||
}
|
47
ListenerGS/RichText/RichText.swift
Normal file
47
ListenerGS/RichText/RichText.swift
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// RichText.swift
|
||||
//
|
||||
//
|
||||
// Created by 이웅재(NuPlay) on 2021/07/26.
|
||||
// https://github.com/NuPlay/RichText
|
||||
|
||||
import SwiftUI
|
||||
|
||||
public struct RichText: View {
|
||||
@State private var dynamicHeight: CGFloat = .zero
|
||||
|
||||
let html: String
|
||||
|
||||
var lineHeight: CGFloat = 170
|
||||
var imageRadius: CGFloat = 0
|
||||
var fontType: fontType = .system
|
||||
|
||||
var colorScheme: colorScheme = .automatic
|
||||
var colorImportant: Bool = false
|
||||
|
||||
var placeholder: AnyView?
|
||||
|
||||
var linkOpenType: linkOpenType = .SFSafariView
|
||||
var linkColor: ColorSet = ColorSet(light: "#007AFF", dark: "#0A84FF")
|
||||
|
||||
public init(html: String) {
|
||||
self.html = html
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
ZStack(alignment: .top) {
|
||||
Webview(dynamicHeight: $dynamicHeight, html: html, lineHeight: lineHeight, imageRadius: imageRadius, fontType: fontType, colorScheme: colorScheme, colorImportant: colorImportant, linkOpenType: linkOpenType, linkColor: linkColor)
|
||||
.frame(height: dynamicHeight)
|
||||
|
||||
if self.dynamicHeight == 0 {
|
||||
placeholder
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RichText_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
RichText(html: "")
|
||||
}
|
||||
}
|
30
ListenerGS/RichText/RichTextEnums.swift
Normal file
30
ListenerGS/RichText/RichTextEnums.swift
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// RichTextEnums.swift
|
||||
//
|
||||
//
|
||||
// Created by 이웅재(NuPlay) on 2021/07/26.
|
||||
// https://github.com/NuPlay/RichText
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum colorScheme: String {
|
||||
case light = "light"
|
||||
case dark = "dark"
|
||||
case automatic = "automatic"
|
||||
}
|
||||
|
||||
public enum fontType: String {
|
||||
case system = "system"
|
||||
case monospaced = "monospaced"
|
||||
case italic = "italic"
|
||||
|
||||
@available(*, deprecated, renamed: "system")
|
||||
case `default` = "default"
|
||||
}
|
||||
|
||||
public enum linkOpenType: String {
|
||||
case SFSafariView = "SFSafariView"
|
||||
case SFSafariViewWithReader = "SFSafariViewWithReader"
|
||||
case Safari = "Safari"
|
||||
case none = "none"
|
||||
}
|
67
ListenerGS/RichText/RichTextExtension.swift
Normal file
67
ListenerGS/RichText/RichTextExtension.swift
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// RichTextExtension.swift
|
||||
//
|
||||
//
|
||||
// Created by 이웅재(NuPlay) on 2021/08/27.
|
||||
// https://github.com/NuPlay/RichText
|
||||
|
||||
import SwiftUI
|
||||
|
||||
extension RichText {
|
||||
|
||||
public func lineHeight(_ lineHeight: CGFloat) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.lineHeight = lineHeight
|
||||
return result
|
||||
}
|
||||
|
||||
public func imageRadius(_ imageRadius: CGFloat) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.imageRadius = imageRadius
|
||||
return result
|
||||
}
|
||||
|
||||
public func fontType(_ fontType: fontType) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.fontType = fontType
|
||||
return result
|
||||
}
|
||||
|
||||
public func colorScheme(_ colorScheme: colorScheme) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.colorScheme = colorScheme
|
||||
return result
|
||||
}
|
||||
|
||||
public func colorImportant(_ colorImportant: Bool) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.colorImportant = colorImportant
|
||||
return result
|
||||
}
|
||||
|
||||
public func placeholder<T>(@ViewBuilder content: () -> T) -> RichText where T: View {
|
||||
var result = self
|
||||
|
||||
result.placeholder = AnyView(content())
|
||||
return result
|
||||
}
|
||||
|
||||
public func linkOpenType(_ linkOpenType: linkOpenType) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.linkOpenType = linkOpenType
|
||||
return result
|
||||
}
|
||||
|
||||
public func linkColor(_ linkColor: ColorSet) -> RichText {
|
||||
var result = self
|
||||
|
||||
result.linkColor = linkColor
|
||||
return result
|
||||
}
|
||||
}
|
184
ListenerGS/RichText/Webview.swift
Normal file
184
ListenerGS/RichText/Webview.swift
Normal file
@ -0,0 +1,184 @@
|
||||
//
|
||||
// Webview.swift
|
||||
//
|
||||
//
|
||||
// Created by 이웅재(NuPlay) on 2021/07/26.
|
||||
// https://github.com/NuPlay/RichText
|
||||
|
||||
import SwiftUI
|
||||
import WebKit
|
||||
import SafariServices
|
||||
|
||||
struct Webview: UIViewRepresentable {
|
||||
|
||||
@Binding var dynamicHeight: CGFloat
|
||||
private var webview: WKWebView = WKWebView()
|
||||
|
||||
let html: String
|
||||
|
||||
let lineHeight: CGFloat
|
||||
let imageRadius: CGFloat
|
||||
let fontType: fontType
|
||||
|
||||
let colorScheme: colorScheme
|
||||
let colorImportant: Bool
|
||||
|
||||
let linkOpenType: linkOpenType
|
||||
let linkColor: ColorSet
|
||||
|
||||
public init(dynamicHeight: Binding<CGFloat>, webview: WKWebView = WKWebView(), html: String, lineHeight: CGFloat, imageRadius: CGFloat, fontType: fontType, colorScheme: colorScheme, colorImportant: Bool, linkOpenType: linkOpenType, linkColor: ColorSet) {
|
||||
self._dynamicHeight = dynamicHeight
|
||||
self.webview = webview
|
||||
|
||||
self.html = html
|
||||
|
||||
self.lineHeight = lineHeight
|
||||
self.imageRadius = imageRadius
|
||||
self.fontType = fontType
|
||||
|
||||
self.colorScheme = colorScheme
|
||||
self.colorImportant = colorImportant
|
||||
|
||||
self.linkOpenType = linkOpenType
|
||||
self.linkColor = linkColor
|
||||
}
|
||||
|
||||
public class Coordinator: NSObject, WKNavigationDelegate {
|
||||
var parent: Webview
|
||||
|
||||
init(_ parent: Webview) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, _) in
|
||||
DispatchQueue.main.async {
|
||||
self.parent.dynamicHeight = height as! CGFloat
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
if navigationAction.navigationType == WKNavigationType.linkActivated {
|
||||
if let url = navigationAction.request.url {
|
||||
|
||||
let root = UIApplication.shared.windows.first?.rootViewController
|
||||
switch self.parent.linkOpenType {
|
||||
case .SFSafariView:
|
||||
root?.present(SFSafariViewController(url: url), animated: true, completion: nil)
|
||||
case .SFSafariViewWithReader:
|
||||
let configuration = SFSafariViewController.Configuration()
|
||||
configuration.entersReaderIfAvailable = true
|
||||
root?.present(SFSafariViewController(url: url, configuration: configuration), animated: true, completion: nil)
|
||||
case .Safari :
|
||||
UIApplication.shared.open(url)
|
||||
case .none :
|
||||
print(url)
|
||||
}
|
||||
}
|
||||
|
||||
decisionHandler(WKNavigationActionPolicy.cancel)
|
||||
return
|
||||
}
|
||||
print("no link")
|
||||
decisionHandler(WKNavigationActionPolicy.allow)
|
||||
}
|
||||
}
|
||||
|
||||
public func makeCoordinator() -> Coordinator {
|
||||
Coordinator(self)
|
||||
}
|
||||
|
||||
public func makeUIView(context: Context) -> WKWebView {
|
||||
webview.scrollView.bounces = false
|
||||
webview.navigationDelegate = context.coordinator
|
||||
webview.scrollView.isScrollEnabled = false
|
||||
let htmlStart = """
|
||||
<HTML>
|
||||
<head>
|
||||
<meta name='viewport' content='width=device-width, shrink-to-fit=YES, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
|
||||
</head>
|
||||
"""
|
||||
let htmlEnd = "</BODY></HTML>"
|
||||
let htmlString = "\(htmlStart)\(css(colorScheme: self.colorScheme))\(html)\(htmlEnd)"
|
||||
webview.loadHTMLString(htmlString, baseURL: nil)
|
||||
webview.isOpaque = false
|
||||
webview.backgroundColor = UIColor.clear
|
||||
webview.scrollView.backgroundColor = UIColor.clear
|
||||
//
|
||||
return webview
|
||||
}
|
||||
|
||||
public func updateUIView(_ uiView: WKWebView, context: Context) {
|
||||
let htmlStart = """
|
||||
<HTML>
|
||||
<head>
|
||||
<meta name='viewport' content='width=device-width, shrink-to-fit=YES, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>
|
||||
</head>
|
||||
"""
|
||||
let htmlEnd = "</BODY></HTML>"
|
||||
let htmlString = "\(htmlStart)\(css(colorScheme: self.colorScheme))\(html)\(htmlEnd)"
|
||||
uiView.loadHTMLString(htmlString, baseURL: nil)
|
||||
}
|
||||
|
||||
func css(colorScheme: colorScheme) -> String {
|
||||
switch colorScheme {
|
||||
case .light:
|
||||
return """
|
||||
<style type='text/css'>
|
||||
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px; border-radius: \(imageRadius)px;}
|
||||
h1, h2, h3, h4, h5, h6, p, dl, ol, ul, pre, blockquote {text-align:left|right|center; line-height: \(lineHeight)%; font-family: '\(fontName(fontType: self.fontType))'; color: #000000 \(colorImportant == false ? "" : "!important"); }
|
||||
iframe{width:100%; height:250px;}
|
||||
a:link {color: \(linkColor.light);}
|
||||
A {text-decoration: none;}
|
||||
</style>
|
||||
<BODY>
|
||||
"""
|
||||
case .dark :
|
||||
return """
|
||||
<style type='text/css'>
|
||||
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px; border-radius: \(imageRadius)px;}
|
||||
h1, h2, h3, h4, h5, h6, p, dl, ol, ul, pre, blockquote {text-align:left|right|center; line-height: \(lineHeight)%; font-family: '\(fontName(fontType: self.fontType))'; color: #F2F2F2 \(colorImportant == false ? "" : "!important"); }
|
||||
iframe{width:100%; height:250px;}
|
||||
a:link {color: \(linkColor.dark);}
|
||||
A {text-decoration: none;}
|
||||
</style>
|
||||
<BODY>
|
||||
"""
|
||||
case .automatic:
|
||||
return """
|
||||
<style type='text/css'>
|
||||
@media (prefers-color-scheme: light) {
|
||||
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px; border-radius: \(imageRadius)px;}
|
||||
h1, h2, h3, h4, h5, h6, p, dl, ol, ul, pre, blockquote {text-align:left|right|center; line-height: \(lineHeight)%; font-family: '\(fontName(fontType: self.fontType))'; color: #000000 \(colorImportant == false ? "" : "!important"); }
|
||||
iframe{width:100%; height:250px;}
|
||||
a:link {color: \(linkColor.light);}
|
||||
A {text-decoration: none;}
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px; border-radius: \(imageRadius)px;}
|
||||
h1, h2, h3, h4, h5, h6, p, dl, ol, ul, pre, blockquote {text-align:left|right|center; line-height: \(lineHeight)%; font-family: '\(fontName(fontType: self.fontType))'; color: #F2F2F2 \(colorImportant == false ? "" : "!important"); }
|
||||
iframe{width:100%; height:250px;}
|
||||
a:link {color: \(linkColor.dark);}
|
||||
A {text-decoration: none;}
|
||||
}
|
||||
</style>
|
||||
<BODY>
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
func fontName(fontType: fontType) -> String {
|
||||
switch fontType {
|
||||
case .system:
|
||||
return "-apple-system"
|
||||
case .monospaced:
|
||||
return UIFont.monospacedSystemFont(ofSize: 17, weight: .regular).fontName
|
||||
case .italic:
|
||||
return UIFont.italicSystemFont(ofSize: 17).fontName
|
||||
|
||||
default :
|
||||
return "-apple-system"
|
||||
}
|
||||
}
|
||||
}
|
@ -10,8 +10,10 @@ I am getting close to making this available as a release that anyone can obtain.
|
||||
|
||||
It relies on the [Speech Framework](https://developer.apple.com/documentation/speech) built into recent versions of iOS.
|
||||
|
||||
This app uses [SwiftSocket v2.1.0](https://github.com/swiftsocket/SwiftSocket/tree/2.1.0) for opening the TCP connection to the Apple IIgs.
|
||||
It also uses [BinUtils](https://github.com/nst/BinUtils) for packing/unpacking structures on the TCP connection.
|
||||
This app uses:
|
||||
* [SwiftSocket v2.1.0](https://github.com/swiftsocket/SwiftSocket/tree/2.1.0) for opening the TCP connection to the Apple IIgs.
|
||||
* [BinUtils](https://github.com/nst/BinUtils) for packing/unpacking structures on the TCP connection.
|
||||
* [RichText v1.7.0](https://github.com/NuPlay/RichText/releases/tag/1.7.0) for displaying a nice startup screen on iPad and macOS.
|
||||
|
||||
## Warning
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user