├── .gitignore
├── Appify AI.app
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ ├── appify-ui-webview
│ └── main.sh
│ └── Resources
│ ├── English.lproj
│ └── MainMenu.nib
│ ├── Node not found Error.html
│ └── app
│ ├── lib
│ ├── http-webview.js
│ └── webview.js
│ └── main.js
├── Appify UI 2011 Demo.app
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ ├── apache-callback-mac
│ └── app.sh
│ └── Resources
│ ├── English.lproj
│ └── MainMenu.nib
│ └── index.html
├── Appify UI 2011 Deno Demo.app
└── Contents
│ ├── .vscode
│ └── settings.json
│ ├── Info.plist
│ ├── MacOS
│ ├── appify-ui-webview
│ └── main.sh
│ └── Resources
│ ├── Deno not found Error.html
│ ├── English.lproj
│ └── MainMenu.nib
│ └── app
│ ├── lib
│ ├── html.ts
│ ├── http-webview.ts
│ ├── webview.html
│ └── webview.ts
│ └── main.ts
├── Appify UI 2011 Node Demo.app
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ ├── appify-ui-webview
│ └── main.sh
│ └── Resources
│ ├── English.lproj
│ └── MainMenu.nib
│ ├── Node not found Error.html
│ └── app
│ ├── lib
│ ├── http-webview.js
│ └── webview.js
│ └── main.js
├── Appify UI 2011.app
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ ├── apache-callback-mac
│ └── appify-ui.sh
│ └── Resources
│ ├── English.lproj
│ └── MainMenu.nib
│ └── index.html
├── Appify UI 2023 Deno.app
└── Contents
│ ├── .vscode
│ └── settings.json
│ ├── Info.plist
│ ├── MacOS
│ ├── Appify UI 23.app
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ ├── MacOS
│ │ │ └── Appify UI 23
│ │ │ ├── PkgInfo
│ │ │ └── _CodeSignature
│ │ │ └── CodeResources
│ └── main.sh
│ └── Resources
│ ├── Deno not found Error.html
│ └── app
│ ├── lib
│ ├── html.ts
│ ├── http-webview.ts
│ ├── webview.html
│ └── webview.ts
│ └── main.ts
├── Appify UI 2023.app
└── Contents
│ ├── Info.plist
│ ├── MacOS
│ └── Appify UI 23
│ ├── PkgInfo
│ └── _CodeSignature
│ └── CodeResources
├── Hello AI.app
└── Contents
│ ├── .vscode
│ └── settings.json
│ ├── Info.plist
│ ├── MacOS
│ ├── Appify UI 23.app
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ ├── MacOS
│ │ │ └── Appify UI 23
│ │ │ ├── PkgInfo
│ │ │ └── _CodeSignature
│ │ │ └── CodeResources
│ └── main.sh
│ └── Resources
│ ├── Deno not found Error.html
│ └── app
│ ├── lib
│ ├── html.ts
│ ├── http-webview.ts
│ ├── webview.html
│ └── webview.ts
│ └── main.ts
├── README.md
├── github.html
├── source
└── Appify UI 23
│ ├── Appify UI 23.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ └── tom.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── tom.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ ├── Appify UI 23
│ ├── Appify_UI_23.entitlements
│ ├── Appify_UI_23App.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
│ └── Appify-UI-23-Info.plist
└── upgrade.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *.tmproj
2 | .DS_Store
3 | *.app.log
4 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 | CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0
2 |
3 | CFBundleIconFile Appify-AI.icns
4 | CFBundleName Appify AI
5 | CFBundleExecutable main.sh
6 | CFBundleIdentifier com.ThingsThatDoStuff.Appify-AI
7 |
8 | NSHumanReadableCopyright © Copyright 2023 Things That So Stuff, LLC
9 | CFBundleVersion 0.1.0
10 | CFBundleShortVersionString 0.1.0
11 |
12 |
13 | NSPrincipalClassNSApplication
14 | NSMainNibFileMainMenu
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/MacOS/appify-ui-webview:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify AI.app/Contents/MacOS/appify-ui-webview
--------------------------------------------------------------------------------
/Appify AI.app/Contents/MacOS/main.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | App="$(dirname "$0")/../.."
4 | cd "$App";App="$PWD"
5 |
6 | function NodeNotFound () {
7 | URL="file://$App/Contents/Resources/Node not found Error.html"
8 | URL="${URL// /%20}"
9 | "$App/Contents/MacOS/appify-ui-webview" -url "${URL}"
10 | exit 1
11 | }
12 |
13 | Node="$App/Contents/MacOS/node"
14 | [[ -f "$Node" ]] || Node="`which node`"
15 | [[ -f "$Node" ]] || Node="/usr/local/bin/node"
16 | [[ -f "$Node" ]] || NodeNotFound
17 |
18 | "$Node" "$App/Contents/Resources/app/main.js" "$@"
19 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Resources/English.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify AI.app/Contents/Resources/English.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Resources/Node not found Error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Can't find Node
4 |
5 | Node.js not found
6 | This app requires Node.js
7 |
8 | Please install
9 |
10 | Node.js
11 | or
12 | Photoshop CC 14.1+
13 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Resources/app/lib/http-webview.js:
--------------------------------------------------------------------------------
1 | const http = require("http")
2 | const webview = require("./webview")
3 |
4 | exports.create = connectionListener => {
5 | let port = 8444
6 | // PROBLEM: localStorage will not be shared between different ports
7 |
8 | const server = http.createServer(connectionListener)
9 |
10 | server.on("listening", () => {
11 | let { address, port } = server.address()
12 | if (address == "::") address = "localhost"
13 | const window = webview.open(`http://${address}:${port}`)
14 |
15 | window.on("exit", () => process.exit(0))
16 | })
17 |
18 | server.on("error", error => {
19 | if (error.code == "EADDRINUSE") {
20 | port++
21 | server.listen(port)
22 | return
23 | }
24 | throw error
25 | })
26 |
27 | server.listen(port)
28 |
29 | server.on("close", () => process.exit(0))
30 |
31 | return server
32 | }
33 |
34 | if (require.main === module) {
35 | exports.create((request, response) => {
36 | response.write("Hello from Node!")
37 | response.end()
38 | })
39 | }
40 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Resources/app/lib/webview.js:
--------------------------------------------------------------------------------
1 | const spawn = require("child_process").spawn
2 |
3 | exports.open = url => {
4 | const child = spawn(`${__dirname}/../../../MacOS/appify-ui-webview`, ["-url", url])
5 | process.on("exit", () => {
6 | child.kill("SIGINT")
7 | })
8 | process.on("beforeExit", () => {
9 | child.kill("SIGINT")
10 | })
11 | return child
12 | }
13 |
14 | if (require.main === module)
15 | exports.open(
16 | "https://github.com/subtleGradient/Appify-UI/blob/master/Appify%20UI%20Node%20Demo.app/Contents/Resources/app/lib/webview.js",
17 | )
18 |
--------------------------------------------------------------------------------
/Appify AI.app/Contents/Resources/app/main.js:
--------------------------------------------------------------------------------
1 | function html(strings, ...values) {
2 | return strings
3 | .map((string, index) => {
4 | let value = values[index]
5 | if (value === undefined) return string
6 | if (typeof value === "function") value = value()
7 | return string + value
8 | })
9 | .join("")
10 | }
11 | const fs = require("fs")
12 | const { exec } = require("child_process")
13 |
14 | const serverModTime = fs.statSync(__filename).mtime
15 | const serverStartTime = new Date()
16 | function indexPage() {
17 | return html`
18 |
19 |
20 | Hello from Node!
21 |
22 | Hello from Node!
23 |
24 | Edit this app
25 |
26 |
29 |
30 |
31 |
36 |
37 |
Server response:
38 |
39 |
40 |
41 |
42 | Address:
43 |
46 |
47 | Modified at: ${serverModTime}
48 | Started at: ${serverStartTime}
49 |
50 | Loaded at: ${new Date()}
51 |
52 | use fetch to load JSON when I click this button:
53 |
54 |
60 |
61 |
62 |
63 |
64 |
81 | `
82 | }
83 |
84 | const router = (request, response) => {
85 | if (request.url === "/") request.url = "/index.html"
86 | if (request.url === "/index.html") {
87 | response.writeHead(200, { "Content-Type": "text/html" })
88 | response.write(indexPage(request))
89 | response.end()
90 | return
91 | }
92 |
93 | if (request.url === "/index.json") {
94 | response.writeHead(200, { "Content-Type": "application/json" })
95 | response.write(JSON.stringify({ hello: "world", time: new Date() }))
96 | response.end()
97 | return
98 | }
99 |
100 | if (request.url === "/kill" && request.method === "POST") {
101 | response.writeHead(200, { "Content-Type": "text/html" })
102 | response.write("Killing server...")
103 | response.end()
104 | setTimeout(() => webviewServer.close(), 0)
105 | return
106 | }
107 |
108 | if (request.url === "/api" && request.method === "POST") {
109 | let body = ""
110 | request.on("data", chunk => {
111 | body += chunk
112 | })
113 |
114 | request.on("end", async () => {
115 | const { text } = JSON.parse(body)
116 | const transformedText = text.split("").reverse().join("")
117 |
118 | response.writeHead(200, { "Content-Type": "application/json" })
119 | response.write(JSON.stringify({ text: transformedText }))
120 | response.end()
121 | })
122 |
123 | return
124 | }
125 |
126 | if (request.url === "/edit" && request.method === "POST") {
127 | exec(`/usr/local/bin/code "${__dirname}/../.."`, err => {
128 | response.writeHead(err ? 500 : 200, { "Content-Type": "application/json" })
129 | response.write(
130 | JSON.stringify(err ? { error: "Failed to execute the command." } : { success: "Command executed successfully." }),
131 | )
132 | response.end()
133 | })
134 | return
135 | }
136 |
137 | response.writeHead(404)
138 | response.end(`Not found: ${request.url}`)
139 | }
140 |
141 | const webviewServer = require("./lib/http-webview").create(router)
142 |
--------------------------------------------------------------------------------
/Appify UI 2011 Demo.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 | CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0
2 |
3 | CFBundleName Appify UI Demo
4 | CFBundleExecutable app.sh
5 | CFBundleIdentifier com.SubtleGradient.appify-ui-demo
6 |
7 | CFBundleVersion 1.0
8 | CFBundleGetInfoString 1.0
9 | CFBundleShortVersionString 1.0
10 |
11 |
12 | NSPrincipalClassNSApplication
13 | NSMainNibFileMainMenu
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Appify UI 2011 Demo.app/Contents/MacOS/apache-callback-mac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Demo.app/Contents/MacOS/apache-callback-mac
--------------------------------------------------------------------------------
/Appify UI 2011 Demo.app/Contents/MacOS/app.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | cd "$(dirname "$0")"
3 |
4 | # launch the cocoa app
5 | ./apache-callback-mac -url "file://$(dirname "$0")/../Resources/index.html"
6 |
--------------------------------------------------------------------------------
/Appify UI 2011 Demo.app/Contents/Resources/English.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Demo.app/Contents/Resources/English.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/Appify UI 2011 Demo.app/Contents/Resources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Appify UI Demo
4 |
5 | Appify UI Demo
6 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "deno.enable": true,
3 | "deno.unstable": true
4 | }
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundlePackageTypeAPPL
5 | CFBundleInfoDictionaryVersion6.0
6 |
7 | CFBundleIconFileAppify-Deno.icns
8 | CFBundleNameAppify Deno
9 | CFBundleExecutablemain.sh
10 | CFBundleIdentifiercom.ThingsThatDoStuff.Appify-Deno
11 |
12 | NSHumanReadableCopyright© Copyright 2023 Things That So Stuff, LLC
13 | CFBundleVersion0.1.0
14 | CFBundleShortVersionString0.1.0
15 |
16 |
17 | NSPrincipalClassNSApplication
18 | NSMainNibFileMainMenu
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/MacOS/appify-ui-webview:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Deno Demo.app/Contents/MacOS/appify-ui-webview
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/MacOS/main.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | App="$(dirname "$0")/../.."
4 | cd "$App";App="$PWD"
5 |
6 | function denoNotFound () {
7 | URL="file://$App/Contents/Resources/Deno not found Error.html"
8 | URL="${URL// /%20}"
9 | "$App/Contents/MacOS/appify-ui-webview" -url "${URL}"
10 | exit 1
11 | }
12 |
13 | function installDeno () {
14 | curl -fsSL https://deno.land/x/install/install.sh | sh
15 | }
16 |
17 | deno="$App/Contents/MacOS/deno" # for packaging deno with the app
18 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
19 | [[ -f "$deno" ]] || deno="`which deno`" # in PATH
20 | [[ -f "$deno" ]] || installDeno
21 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
22 | [[ -f "$deno" ]] || deno="`which deno`" # in PATH
23 | [[ -f "$deno" ]] || denoNotFound
24 |
25 | MAIN="$App/Contents/Resources/app/main.ts"
26 |
27 | "$deno" run --allow-read --allow-write --allow-net --allow-env --allow-run "$MAIN" "$@"
28 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/Deno not found Error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Can't find Deno
4 |
5 | Deno not found
6 | This app requires Deno
7 |
8 | Please install Deno and try again.
9 |
10 | - Install the latest Deno: https://deno.land/manual/getting_started/installation
11 | - Install Deno version 1.32.3 https://deno.land/manual@v1.32.3/getting_started/installation
12 |
13 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/English.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Deno Demo.app/Contents/Resources/English.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/app/lib/html.ts:
--------------------------------------------------------------------------------
1 | // const WebviewServer = await import("./lib/http-webview");
2 | export function html(strings: TemplateStringsArray, ...values: unknown[]): string {
3 | return strings
4 | .map((string, index) => {
5 | let value = values[index];
6 | if (value === undefined)
7 | return string;
8 | if (typeof value === "function")
9 | value = value();
10 | return string + value;
11 | })
12 | .join("");
13 | }
14 |
15 | export const css = html
16 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/app/lib/http-webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | import { open } from "./webview.ts"
5 | import { type Handler, Server } from "https://deno.land/std@0.182.0/http/server.ts"
6 |
7 | export function create(handler: Handler) {
8 | let port = 8444
9 | // TODO: try this port first, if it's not available, try the next one, and so on
10 |
11 | const server = new Server({ port, handler })
12 | server.listenAndServe()
13 |
14 | const window = open(`http://0.0.0.0:${port}`)
15 | window.status().then(status => {
16 | // kill the server when the window closes
17 | server.close()
18 | // kill the deno process when the window closes
19 | Deno.exit(status.code)
20 | })
21 |
22 | return server
23 | }
24 |
25 | import { html, css } from "./html.ts"
26 |
27 | if (import.meta.main) {
28 | console.log("webview works?")
29 |
30 | create(_req => {
31 | console.log("webview works!")
32 |
33 | const styles = css`
34 | :root {
35 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
36 | "Helvetica Neue", sans-serif;
37 | }
38 | `
39 | const body = html`
40 |
43 |
44 | lulz 1
45 | `
46 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
47 | })
48 | }
49 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/app/lib/webview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | webview
8 |
9 |
10 | webview works!
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/app/lib/webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | const WEBVIEW_BIN = `${__dirname}/../../../MacOS/appify-ui-webview`;
5 |
6 | export function open(url: URL | string) {
7 | if (url.toString().startsWith("/")) url = `file://${url}`;
8 | if (typeof url === "string") url = new URL(url);
9 |
10 | const child = Deno.run({
11 | cmd: [WEBVIEW_BIN, "-url", url.href],
12 | stdout: "inherit",
13 | stderr: "inherit",
14 | });
15 |
16 | // wait for process to exit
17 | child.status().then(status => console.log({ status }));
18 |
19 | return child;
20 | }
21 |
22 | if (import.meta.main) open(`${__dirname}/webview.html`)
23 |
--------------------------------------------------------------------------------
/Appify UI 2011 Deno Demo.app/Contents/Resources/app/main.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | import * as webviewServer from "./lib/http-webview.ts"
5 | import { html, css } from "./lib/html.ts"
6 |
7 | const handlerMainView = (_req: Request): Response => {
8 | console.log("webview works!")
9 |
10 | const styles = css`
11 | :root {
12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
13 | "Helvetica Neue", sans-serif;
14 | }
15 | `
16 | const body = html`
17 |
20 |
21 | Appify UI (powered by Deno)
22 |
23 |
24 | Edit this app
25 |
26 |
29 |
30 | `
31 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
32 | }
33 |
34 | const handlerEdit = async (req: Request): Promise => {
35 | console.log("handlerEdit")
36 | if (req.method !== "POST") {
37 | console.warn("Error; Endpoint requires POST")
38 | return new Response("Error; Endpoint requires POST", { status: 400, headers: { "content-type": "text/html" } })
39 | }
40 | if (Deno.build.os !== "darwin") {
41 | console.warn("NOT IMPLEMENTED")
42 | return new Response("NOT IMPLEMENTED", { status: 400, headers: { "content-type": "text/html" } })
43 | } else {
44 | console.log("Opening VSCode…")
45 | const vscode = Deno.run({
46 | cmd: ["/usr/local/bin/code", `${__dirname}/../..`],
47 | stdout: "piped",
48 | stderr: "piped",
49 | })
50 | const { code } = await vscode.status()
51 | console.log("VSCode exited with code", code)
52 | if (code !== 0) {
53 | const rawError = await vscode.stderrOutput()
54 | const errorString = new TextDecoder().decode(rawError)
55 | return new Response(errorString, { status: 500, headers: { "content-type": "text/html" } })
56 | }
57 | return new Response("Done", { status: 200, headers: { "content-type": "text/html" } })
58 | }
59 | }
60 |
61 | const handlerRouter = async (req: Request): Promise => {
62 | console.log("handlerRouter", req.url)
63 | if (new URL(req.url).pathname === "/edit") return await handlerEdit(req)
64 | return handlerMainView(req)
65 | }
66 |
67 | if (import.meta.main) {
68 | console.log("starting webview server…")
69 | webviewServer.create(handlerRouter)
70 | }
71 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 | CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0
2 |
3 | CFBundleName Appify UI Node Demo
4 | CFBundleExecutable main.sh
5 | CFBundleIdentifier com.SubtleGradient.appify-ui-node-demo
6 |
7 | CFBundleVersion 1.0
8 | CFBundleGetInfoString 1.0
9 | CFBundleShortVersionString 1.0
10 |
11 |
12 | NSPrincipalClassNSApplication
13 | NSMainNibFileMainMenu
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/MacOS/appify-ui-webview:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Node Demo.app/Contents/MacOS/appify-ui-webview
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/MacOS/main.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | App="$(dirname "$0")/../.."
4 | cd "$App";App="$PWD"
5 |
6 | function NodeNotFound () {
7 | URL="file://$App/Contents/Resources/Node not found Error.html"
8 | URL="${URL// /%20}"
9 | "$App/Contents/MacOS/appify-ui-webview" -url "${URL}"
10 | exit 1
11 | }
12 |
13 | Node="$App/Contents/MacOS/node"
14 | [[ -f "$Node" ]] || Node="`which node`"
15 | [[ -f "$Node" ]] || Node="/usr/local/bin/node"
16 | [[ -f "$Node" ]] || NodeNotFound
17 |
18 | "$Node" "$App/Contents/Resources/app/main.js" "$@"
19 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Resources/English.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011 Node Demo.app/Contents/Resources/English.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Resources/Node not found Error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Can't find Node
4 |
5 | Node.js not found
6 | This app requires Node.js
7 |
8 | Please install
9 |
10 | Node.js
11 | or
12 | Photoshop CC 14.1+
13 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Resources/app/lib/http-webview.js:
--------------------------------------------------------------------------------
1 | const http = require("http")
2 | const webview = require("./webview")
3 |
4 | exports.create = connectionListener => {
5 | let port = 8444
6 | // PROBLEM: localStorage will not be shared between different ports
7 |
8 | const server = http.createServer(connectionListener)
9 |
10 | server.on("listening", () => {
11 | let { address, port } = server.address()
12 | if (address == "::") address = "localhost"
13 | const window = webview.open(`http://${address}:${port}`)
14 |
15 | window.on("exit", () => process.exit(0))
16 | })
17 |
18 | server.on("error", error => {
19 | if (error.code == "EADDRINUSE") {
20 | port++
21 | server.listen(port)
22 | return
23 | }
24 | throw error
25 | })
26 |
27 | server.listen(port)
28 |
29 | server.on("close", () => webview.close())
30 |
31 | return server
32 | }
33 |
34 | if (require.main === module) {
35 | exports.create((request, response) => {
36 | response.write("Hello from Node!")
37 | response.end()
38 | })
39 | }
40 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Resources/app/lib/webview.js:
--------------------------------------------------------------------------------
1 | const spawn = require("child_process").spawn
2 |
3 | exports.open = url => spawn(`${__dirname}/../../../MacOS/appify-ui-webview`, ["-url", url])
4 |
5 | if (require.main === module)
6 | exports.open(
7 | "https://github.com/subtleGradient/Appify-UI/blob/master/Appify%20UI%20Node%20Demo.app/Contents/Resources/app/lib/webview.js",
8 | )
9 |
--------------------------------------------------------------------------------
/Appify UI 2011 Node Demo.app/Contents/Resources/app/main.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs")
2 | const serverModTime = fs.statSync(__filename).mtime
3 | const serverStartTime = new Date()
4 |
5 | const webviewServer = require("./lib/http-webview").create((request, response) => {
6 | response.write(`
7 |
8 |
9 | Hello from Node!
10 |
11 | Hello from Node!
12 |
13 | Edit this app
14 |
15 |
16 |
17 | Modified at: ${serverModTime}
18 | Started at: ${serverStartTime}
19 | Loaded at: ${new Date()}
20 | `)
21 |
22 | const wasModified = fs.statSync(__filename).mtime > serverStartTime
23 | if (wasModified) {
24 | response.write(`Server code was modified. Kill the app and relaunch it to see the changes
`)
25 | }
26 |
27 | response.end()
28 | })
29 |
--------------------------------------------------------------------------------
/Appify UI 2011.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 | CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0
2 |
3 | CFBundleName Appify UI
4 | CFBundleExecutable appify-ui.sh
5 | CFBundleIdentifier com.SubtleGradient.AppifyUI
6 |
7 | CFBundleVersion 1.0
8 | CFBundleGetInfoString 1.0 Appified by Thomas Aylott on Sat Dec 3 2011
9 | CFBundleShortVersionString 1.0
10 |
11 | NSPrincipalClassNSApplication
12 | NSMainNibFileMainMenu
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Appify UI 2011.app/Contents/MacOS/apache-callback-mac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011.app/Contents/MacOS/apache-callback-mac
--------------------------------------------------------------------------------
/Appify UI 2011.app/Contents/MacOS/appify-ui.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # MIT License
4 | #
5 | # Created By
6 | # Thomas Aylott
7 | #
8 | # Special Thanks
9 | # Mathias Bynens
10 | # Shazron Abdullah
11 | # Apache Callback Mac (heavily modified)
12 | # Marc Wäckerlin
13 |
14 |
15 | # Decodes an URL-string
16 | # an URL encoding has "+" instead of spaces
17 | # and no special characters but "%HEX"
18 | function urlDec() {
19 | local value=${*//+/%20} # replace +-spaces by %20 (hex)
20 | for part in ${value//%/ \\x}; do # split at % prepend \x for printf
21 | printf "%b%s" "${part:0:4}" "${part:4}" # output decoded char
22 | done
23 | }
24 |
25 | # For all given query strings
26 | # parse them an set shell variables
27 | function setQueryVars() {
28 | local vars="$(cat)"
29 | local vars="${vars//\*/%2A}" # escape * as %2A
30 | for var in ${vars//&/ }; do # split at &
31 | local value=$(urlDec "${var#*=}") # decode value after =
32 | value=${value//\\/\\\\} # change \ to \\ for later
33 | eval "CGI_${var%=*}=\"${value//\"/\\\"}\"" # evaluate assignment
34 | done
35 | }
36 |
37 | function handleForm () {
38 | appify
39 | }
40 |
41 | function appify () {
42 | setQueryVars
43 |
44 | cd "$HOME/Desktop"
45 |
46 | # Options
47 | local appify_FILE="$CGI_CFBundleExecutable"
48 | local appify_NAME="$CGI_CFBundleName"
49 | local appify_ROOT="$appify_NAME.appify/Contents/MacOS"
50 | local appify_INFO="$appify_ROOT/../Info.plist"
51 |
52 | if [[ "$appify_FILE" == "" ]]; then
53 | echo "CFBundleExecutable is required. Aborting" 1>&2
54 | exit 1
55 | fi
56 |
57 | # Create the bundle
58 | if [[ -a "$appify_NAME.appify" ]]; then
59 | echo "$PWD/$appify_NAME.appify already exists :(" 1>&2
60 | exit 1
61 | fi
62 | mkdir -p "$appify_ROOT"
63 |
64 |
65 | # Create a new blank CFBundleExecutable
66 | cat <<-EOF > "$appify_ROOT/$appify_FILE"
67 | #!/usr/bin/env bash
68 | # launch the cocoa app
69 | cd "\$(dirname "\$0")"
70 | ./apache-callback-mac -url "file://\$(dirname "\$0")/../Resources/index.html"
71 | EOF
72 | echo "Created blank '$appify_ROOT/$appify_FILE' be sure to edit this file to make it do things and stuff" 1>&2
73 |
74 | chmod +x "$appify_ROOT/$appify_FILE"
75 |
76 | cp "$(dirname "$0")/apache-callback-mac" "$appify_ROOT/"
77 | mkdir -p "$appify_ROOT/../Resources/English.lproj"
78 | cp "$(dirname "$0")/../Resources/English.lproj/MainMenu.nib" "$appify_ROOT/../Resources/English.lproj/MainMenu.nib"
79 | cat <<-EOF > "$appify_ROOT/../Resources/index.html"
80 |
81 |
82 | $appify_NAME
83 |
84 | $appify_NAME
85 | EOF
86 |
87 | # Create the Info.plist
88 | cat <<-EOF > "$appify_INFO"
89 | CFBundlePackageTypeAPPLCFBundleInfoDictionaryVersion6.0
90 |
91 | CFBundleIconFile $CGI_CFBundleIconFile
92 |
93 | CFBundleName $CGI_CFBundleName
94 | CFBundleExecutable $CGI_CFBundleExecutable
95 | CFBundleIdentifier $CGI_CFBundleIdentifier
96 |
97 | CFBundleVersion $CGI_CFBundleVersion
98 | NSHumanReadableCopyright $CGI_NSHumanReadableCopyright
99 | CFBundleShortVersionString $CGI_CFBundleShortVersionString
100 |
101 |
102 | NSPrincipalClassNSApplication
103 | NSMainNibFileMainMenu
104 |
105 |
106 | EOF
107 |
108 | # Appify!
109 | if [[ -a "$appify_NAME.app" ]]; then
110 | echo "$appify_NAME.app already exists :(" 1>&2
111 | exit 1
112 | fi
113 | mv "$appify_NAME.appify" "$appify_NAME.app"
114 |
115 | exit
116 | }
117 |
118 | function waitForFormData () {
119 | cat < /dev/null
141 |
--------------------------------------------------------------------------------
/Appify UI 2011.app/Contents/Resources/English.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2011.app/Contents/Resources/English.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/Appify UI 2011.app/Contents/Resources/index.html:
--------------------------------------------------------------------------------
1 |
2 | Appify
3 |
4 |
5 |
39 |
40 |
41 |
48 |
49 |
66 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "deno.enable": true,
3 | "deno.unstable": true
4 | }
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundlePackageTypeAPPL
5 | CFBundleInfoDictionaryVersion6.0
6 |
7 | CFBundleIconFileAppify-Deno.icns
8 | CFBundleNameAppify Deno
9 | CFBundleExecutablemain.sh
10 | CFBundleIdentifiercom.ThingsThatDoStuff.Appify-Deno
11 |
12 | NSHumanReadableCopyright© Copyright 2023 Things That So Stuff, LLC
13 | CFBundleVersion0.1.0
14 | CFBundleShortVersionString0.1.0
15 |
16 |
17 | NSPrincipalClassNSApplication
18 | NSMainNibFileMainMenu
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/MacOS/Appify UI 23.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 22D68
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | Appify UI 23
11 | CFBundleIdentifier
12 | com.ThingsThatDoStuff.Appify-UI-23
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Appify UI 23
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSupportedPlatforms
22 |
23 | MacOSX
24 |
25 | CFBundleVersion
26 | 1
27 | DTCompiler
28 | com.apple.compilers.llvm.clang.1_0
29 | DTPlatformBuild
30 |
31 | DTPlatformName
32 | macosx
33 | DTPlatformVersion
34 | 13.3
35 | DTSDKBuild
36 | 22E245
37 | DTSDKName
38 | macosx13.3
39 | DTXcode
40 | 1430
41 | DTXcodeBuild
42 | 14E222b
43 | LSMinimumSystemVersion
44 | 13.2
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2023 Deno.app/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/MacOS/Appify UI 23.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/MacOS/Appify UI 23.app/Contents/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | files2
8 |
9 | rules
10 |
11 | ^Resources/
12 |
13 | ^Resources/.*\.lproj/
14 |
15 | optional
16 |
17 | weight
18 | 1000
19 |
20 | ^Resources/.*\.lproj/locversion.plist$
21 |
22 | omit
23 |
24 | weight
25 | 1100
26 |
27 | ^Resources/Base\.lproj/
28 |
29 | weight
30 | 1010
31 |
32 | ^version.plist$
33 |
34 |
35 | rules2
36 |
37 | .*\.dSYM($|/)
38 |
39 | weight
40 | 11
41 |
42 | ^(.*/)?\.DS_Store$
43 |
44 | omit
45 |
46 | weight
47 | 2000
48 |
49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
50 |
51 | nested
52 |
53 | weight
54 | 10
55 |
56 | ^.*
57 |
58 | ^Info\.plist$
59 |
60 | omit
61 |
62 | weight
63 | 20
64 |
65 | ^PkgInfo$
66 |
67 | omit
68 |
69 | weight
70 | 20
71 |
72 | ^Resources/
73 |
74 | weight
75 | 20
76 |
77 | ^Resources/.*\.lproj/
78 |
79 | optional
80 |
81 | weight
82 | 1000
83 |
84 | ^Resources/.*\.lproj/locversion.plist$
85 |
86 | omit
87 |
88 | weight
89 | 1100
90 |
91 | ^Resources/Base\.lproj/
92 |
93 | weight
94 | 1010
95 |
96 | ^[^/]+$
97 |
98 | nested
99 |
100 | weight
101 | 10
102 |
103 | ^embedded\.provisionprofile$
104 |
105 | weight
106 | 20
107 |
108 | ^version\.plist$
109 |
110 | weight
111 | 20
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/MacOS/main.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | App="$(dirname "$0")/../.."
4 | cd "$App"
5 | App="$PWD"
6 |
7 | denoNotFound() {
8 | URL="file://$App/Contents/Resources/Deno not found Error.html"
9 | URL="${URL// /%20}"
10 | "$App/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23" --url "${URL}"
11 | exit 1
12 | }
13 |
14 | installDeno() {
15 | curl -fsSL https://deno.land/install.sh | sh
16 | }
17 |
18 | main() {
19 | deno="$App/Contents/MacOS/deno" # for packaging deno with the app
20 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
21 | [[ -f "$deno" ]] || deno="$(which deno)" # in PATH
22 | [[ -f "$deno" ]] || installDeno
23 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
24 | [[ -f "$deno" ]] || deno="$(which deno)" # in PATH
25 | [[ -f "$deno" ]] || denoNotFound
26 |
27 | MAIN="$App/Contents/Resources/app/main.ts"
28 |
29 | "$deno" run --allow-read --allow-write --allow-net --allow-env --allow-run "$MAIN" "$@"
30 | }
31 |
32 | main "$@" >"$App.log" 2>&1
33 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/Deno not found Error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Can't find Deno
4 |
5 | Deno not found
6 | This app requires Deno
7 |
8 | Please install Deno and try again.
9 |
10 | - Install the latest Deno: https://deno.land/manual/getting_started/installation
11 | - Install Deno version 1.32.3 https://deno.land/manual@v1.32.3/getting_started/installation
12 |
13 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/app/lib/html.ts:
--------------------------------------------------------------------------------
1 | // const WebviewServer = await import("./lib/http-webview");
2 | export function html(strings: TemplateStringsArray, ...values: unknown[]): string {
3 | return strings
4 | .map((string, index) => {
5 | let value = values[index];
6 | if (value === undefined)
7 | return string;
8 | if (typeof value === "function")
9 | value = value();
10 | return string + value;
11 | })
12 | .join("");
13 | }
14 |
15 | export const css = html
16 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/app/lib/http-webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | import { type Handler, Server } from "https://deno.land/std@0.224.0/http/server.ts"
5 | import { open } from "./webview.ts"
6 |
7 | export function create(handler: Handler) {
8 | const port = 8444
9 | // TODO: try this port first, if it's not available, try the next one, and so on
10 |
11 | const server = new Server({ port, handler })
12 | server.listenAndServe()
13 |
14 | const window = open(`http://localhost:${port}`)
15 | window.status().then(status => {
16 | // kill the server when the window closes
17 | server.close()
18 | // kill the deno process when the window closes
19 | Deno.exit(status.code)
20 | })
21 |
22 | return server
23 | }
24 |
25 | import { css, html } from "./html.ts"
26 |
27 | if (import.meta.main) {
28 | console.log("webview works?")
29 |
30 | create(_req => {
31 | console.log("webview works!")
32 |
33 | const styles = css`
34 | :root {
35 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
36 | "Helvetica Neue", sans-serif;
37 | }
38 | `
39 | const body = html`
40 |
43 |
44 | lulz 1
45 | `
46 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
47 | })
48 | }
49 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/app/lib/webview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | webview
8 |
9 |
10 | webview works!
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/app/lib/webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | const [APP_ROOT] = __dirname.split("/Contents/")
5 |
6 | const WEBVIEW_BIN = `${APP_ROOT}/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23`
7 |
8 | export function open(url: URL | string) {
9 | if (url.toString().startsWith("/")) url = `file://${url}`
10 | if (typeof url === "string") url = new URL(url)
11 |
12 | console.log(__filename, "open", url.href)
13 |
14 | const child = Deno.run({
15 | cmd: [WEBVIEW_BIN, "--url", url.href],
16 | stdout: "inherit",
17 | stderr: "inherit",
18 | })
19 |
20 | // wait for process to exit
21 | child.status().then(status => console.log({ status }))
22 |
23 | return child
24 | }
25 |
26 | if (import.meta.main) open(`${__dirname}/webview.html`)
27 |
--------------------------------------------------------------------------------
/Appify UI 2023 Deno.app/Contents/Resources/app/main.ts:
--------------------------------------------------------------------------------
1 | // TODO: Add a GPT-4 powered Bible verse search app
2 | // TODO: Add a SharePoint view editor
3 |
4 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
5 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
6 |
7 | import { css, html } from "./lib/html.ts"
8 | import * as webviewServer from "./lib/http-webview.ts"
9 |
10 | const styles = css`
11 | :root {
12 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
13 | "Helvetica Neue", sans-serif;
14 | }
15 | `
16 |
17 | const handlerMainView = (_req: Request): Response => {
18 | console.log("webview works!")
19 |
20 | const body = html`
21 |
24 |
25 | Appify UI (powered by Deno)
26 |
27 |
28 | Edit this app
29 |
30 |
31 |
34 |
35 | `
36 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
37 | }
38 |
39 | const handlerEdit = async (req: Request): Promise => {
40 | const url = new URL(req.url)
41 | const wantsInsiders = url.searchParams.get("insiders") === "1"
42 |
43 | console.log("handlerEdit")
44 | if (req.method !== "POST") {
45 | console.warn("Error; Endpoint requires POST")
46 | return new Response("Error; Endpoint requires POST", { status: 400, headers: { "content-type": "text/html" } })
47 | }
48 | if (Deno.build.os !== "darwin") {
49 | console.warn("NOT IMPLEMENTED")
50 | return new Response("NOT IMPLEMENTED", { status: 400, headers: { "content-type": "text/html" } })
51 | } else {
52 | console.log("Opening VSCode…")
53 | const vscode = Deno.run({
54 | cmd: ["/usr/local/bin/code" + (wantsInsiders ? "-insiders" : ""), `${__dirname}/../..`],
55 | stdout: "piped",
56 | stderr: "piped",
57 | })
58 | const { code } = await vscode.status()
59 | console.log("VSCode exited with code", code)
60 | if (code !== 0) {
61 | const rawError = await vscode.stderrOutput()
62 | const errorString = new TextDecoder().decode(rawError)
63 | return new Response(errorString, { status: 500, headers: { "content-type": "text/html" } })
64 | }
65 | return new Response("Done", { status: 200, headers: { "content-type": "text/html" } })
66 | }
67 | }
68 |
69 | const handlerRouter = async (req: Request): Promise => {
70 | console.log("handlerRouter", req.url)
71 | if (new URL(req.url).pathname === "/edit") return await handlerEdit(req)
72 | return handlerMainView(req)
73 | }
74 |
75 | if (import.meta.main) {
76 | console.log("starting webview server…")
77 | webviewServer.create(handlerRouter)
78 | }
79 |
--------------------------------------------------------------------------------
/Appify UI 2023.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 22D68
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | Appify UI 23
11 | CFBundleIdentifier
12 | com.ThingsThatDoStuff.Appify-UI-23
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Appify UI 23
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSupportedPlatforms
22 |
23 | MacOSX
24 |
25 | CFBundleVersion
26 | 1
27 | DTCompiler
28 | com.apple.compilers.llvm.clang.1_0
29 | DTPlatformBuild
30 |
31 | DTPlatformName
32 | macosx
33 | DTPlatformVersion
34 | 13.3
35 | DTSDKBuild
36 | 22E245
37 | DTSDKName
38 | macosx13.3
39 | DTXcode
40 | 1430
41 | DTXcodeBuild
42 | 14E222b
43 | LSMinimumSystemVersion
44 | 13.2
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Appify UI 2023.app/Contents/MacOS/Appify UI 23:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Appify UI 2023.app/Contents/MacOS/Appify UI 23
--------------------------------------------------------------------------------
/Appify UI 2023.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/Appify UI 2023.app/Contents/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | files2
8 |
9 | rules
10 |
11 | ^Resources/
12 |
13 | ^Resources/.*\.lproj/
14 |
15 | optional
16 |
17 | weight
18 | 1000
19 |
20 | ^Resources/.*\.lproj/locversion.plist$
21 |
22 | omit
23 |
24 | weight
25 | 1100
26 |
27 | ^Resources/Base\.lproj/
28 |
29 | weight
30 | 1010
31 |
32 | ^version.plist$
33 |
34 |
35 | rules2
36 |
37 | .*\.dSYM($|/)
38 |
39 | weight
40 | 11
41 |
42 | ^(.*/)?\.DS_Store$
43 |
44 | omit
45 |
46 | weight
47 | 2000
48 |
49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
50 |
51 | nested
52 |
53 | weight
54 | 10
55 |
56 | ^.*
57 |
58 | ^Info\.plist$
59 |
60 | omit
61 |
62 | weight
63 | 20
64 |
65 | ^PkgInfo$
66 |
67 | omit
68 |
69 | weight
70 | 20
71 |
72 | ^Resources/
73 |
74 | weight
75 | 20
76 |
77 | ^Resources/.*\.lproj/
78 |
79 | optional
80 |
81 | weight
82 | 1000
83 |
84 | ^Resources/.*\.lproj/locversion.plist$
85 |
86 | omit
87 |
88 | weight
89 | 1100
90 |
91 | ^Resources/Base\.lproj/
92 |
93 | weight
94 | 1010
95 |
96 | ^[^/]+$
97 |
98 | nested
99 |
100 | weight
101 | 10
102 |
103 | ^embedded\.provisionprofile$
104 |
105 | weight
106 | 20
107 |
108 | ^version\.plist$
109 |
110 | weight
111 | 20
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "deno.enable": true,
3 | "deno.unstable": true
4 | }
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundlePackageTypeAPPL
5 | CFBundleInfoDictionaryVersion6.0
6 |
7 | CFBundleIconFileHello-AI.icns
8 | CFBundleNameHello AI
9 | CFBundleExecutablemain.sh
10 | CFBundleIdentifiercom.ThingsThatDoStuff.Appify.Hello-AI
11 |
12 | NSHumanReadableCopyright© Copyright 2023 Things That So Stuff, LLC
13 | CFBundleVersion0.1.0
14 | CFBundleShortVersionString0.1.0
15 |
16 |
17 | NSPrincipalClassNSApplication
18 | NSMainNibFileMainMenu
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/MacOS/Appify UI 23.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 22D68
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | Appify UI 23
11 | CFBundleIdentifier
12 | com.ThingsThatDoStuff.Appify-UI-23
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | Appify UI 23
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSupportedPlatforms
22 |
23 | MacOSX
24 |
25 | CFBundleVersion
26 | 1
27 | DTCompiler
28 | com.apple.compilers.llvm.clang.1_0
29 | DTPlatformBuild
30 |
31 | DTPlatformName
32 | macosx
33 | DTPlatformVersion
34 | 13.3
35 | DTSDKBuild
36 | 22E245
37 | DTSDKName
38 | macosx13.3
39 | DTXcode
40 | 1430
41 | DTXcodeBuild
42 | 14E222b
43 | LSMinimumSystemVersion
44 | 13.2
45 |
46 |
47 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/Hello AI.app/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23
--------------------------------------------------------------------------------
/Hello AI.app/Contents/MacOS/Appify UI 23.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/Hello AI.app/Contents/MacOS/Appify UI 23.app/Contents/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | files2
8 |
9 | rules
10 |
11 | ^Resources/
12 |
13 | ^Resources/.*\.lproj/
14 |
15 | optional
16 |
17 | weight
18 | 1000
19 |
20 | ^Resources/.*\.lproj/locversion.plist$
21 |
22 | omit
23 |
24 | weight
25 | 1100
26 |
27 | ^Resources/Base\.lproj/
28 |
29 | weight
30 | 1010
31 |
32 | ^version.plist$
33 |
34 |
35 | rules2
36 |
37 | .*\.dSYM($|/)
38 |
39 | weight
40 | 11
41 |
42 | ^(.*/)?\.DS_Store$
43 |
44 | omit
45 |
46 | weight
47 | 2000
48 |
49 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
50 |
51 | nested
52 |
53 | weight
54 | 10
55 |
56 | ^.*
57 |
58 | ^Info\.plist$
59 |
60 | omit
61 |
62 | weight
63 | 20
64 |
65 | ^PkgInfo$
66 |
67 | omit
68 |
69 | weight
70 | 20
71 |
72 | ^Resources/
73 |
74 | weight
75 | 20
76 |
77 | ^Resources/.*\.lproj/
78 |
79 | optional
80 |
81 | weight
82 | 1000
83 |
84 | ^Resources/.*\.lproj/locversion.plist$
85 |
86 | omit
87 |
88 | weight
89 | 1100
90 |
91 | ^Resources/Base\.lproj/
92 |
93 | weight
94 | 1010
95 |
96 | ^[^/]+$
97 |
98 | nested
99 |
100 | weight
101 | 10
102 |
103 | ^embedded\.provisionprofile$
104 |
105 | weight
106 | 20
107 |
108 | ^version\.plist$
109 |
110 | weight
111 | 20
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/MacOS/main.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | App="$(dirname "$0")/../.."
4 | cd "$App";App="$PWD"
5 |
6 | function denoNotFound () {
7 | URL="file://$App/Contents/Resources/Deno not found Error.html"
8 | URL="${URL// /%20}"
9 | "$App/Contents/MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23" --url "${URL}"
10 | exit 1
11 | }
12 |
13 | function installDeno () {
14 | curl -fsSL https://deno.land/x/install/install.sh | sh
15 | }
16 |
17 | deno="$App/Contents/MacOS/deno" # for packaging deno with the app
18 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
19 | [[ -f "$deno" ]] || deno="`which deno`" # in PATH
20 | [[ -f "$deno" ]] || installDeno
21 | [[ -f "$deno" ]] || deno="$HOME/.deno/bin/deno" # default install location
22 | [[ -f "$deno" ]] || deno="`which deno`" # in PATH
23 | [[ -f "$deno" ]] || denoNotFound
24 |
25 | MAIN="$App/Contents/Resources/app/main.ts"
26 |
27 | "$deno" run --allow-read --allow-write --allow-net --allow-env --allow-run "$MAIN" "$@"
28 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/Deno not found Error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Can't find Deno
4 |
5 | Deno not found
6 | This app requires Deno
7 |
8 | Please install Deno and try again.
9 |
10 | - Install the latest Deno: https://deno.land/manual/getting_started/installation
11 | - Install Deno version 1.32.3 https://deno.land/manual@v1.32.3/getting_started/installation
12 |
13 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/app/lib/html.ts:
--------------------------------------------------------------------------------
1 | // const WebviewServer = await import("./lib/http-webview");
2 | export function html(strings: TemplateStringsArray, ...values: unknown[]): string {
3 | return strings
4 | .map((string, index) => {
5 | let value = values[index];
6 | if (value === undefined)
7 | return string;
8 | if (typeof value === "function")
9 | value = value();
10 | return string + value;
11 | })
12 | .join("");
13 | }
14 |
15 | export const css = html
16 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/app/lib/http-webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | import { open } from "./webview.ts"
5 | import { type Handler, Server } from "https://deno.land/std@0.182.0/http/server.ts"
6 |
7 | export function create(handler: Handler) {
8 | let port = 8444
9 | // TODO: try this port first, if it's not available, try the next one, and so on
10 |
11 | const server = new Server({ port, handler })
12 | server.listenAndServe()
13 |
14 | const window = open(`http://0.0.0.0:${port}`)
15 | window.status().then(status => {
16 | // kill the server when the window closes
17 | server.close()
18 | // kill the deno process when the window closes
19 | Deno.exit(status.code)
20 | })
21 |
22 | return server
23 | }
24 |
25 | import { html, css } from "./html.ts"
26 |
27 | if (import.meta.main) {
28 | console.log("webview works?")
29 |
30 | create(_req => {
31 | console.log("webview works!")
32 |
33 | const styles = css`
34 | :root {
35 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
36 | "Helvetica Neue", sans-serif;
37 | }
38 | `
39 | const body = html`
40 |
43 |
44 | lulz 1
45 | `
46 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
47 | })
48 | }
49 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/app/lib/webview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | webview
8 |
9 |
10 | webview works!
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/app/lib/webview.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | const WEBVIEW_BIN = `${__dirname}/../../../MacOS/Appify UI 23.app/Contents/MacOS/Appify UI 23`;
5 |
6 | export function open(url: URL | string) {
7 | if (url.toString().startsWith("/")) url = `file://${url}`;
8 | if (typeof url === "string") url = new URL(url);
9 |
10 | const child = Deno.run({
11 | cmd: [WEBVIEW_BIN, "--url", url.href],
12 | stdout: "inherit",
13 | stderr: "inherit",
14 | });
15 |
16 | // wait for process to exit
17 | child.status().then(status => console.log({ status }));
18 |
19 | return child;
20 | }
21 |
22 | if (import.meta.main) open(`${__dirname}/webview.html`)
23 |
--------------------------------------------------------------------------------
/Hello AI.app/Contents/Resources/app/main.ts:
--------------------------------------------------------------------------------
1 | const __filename = decodeURIComponent(new URL(import.meta.url).pathname)
2 | const __dirname = __filename.slice(0, __filename.lastIndexOf("/"))
3 |
4 | import * as webviewServer from "./lib/http-webview.ts"
5 | import { html, css } from "./lib/html.ts"
6 |
7 | const styles = css`
8 | :root {
9 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
10 | "Helvetica Neue", sans-serif;
11 | }
12 | `
13 |
14 | const handlerMainView = (_req: Request): Response => {
15 | console.log("webview works!")
16 |
17 | const body = html`
18 |
21 |
22 |
23 |
24 | Edit this app
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | `
58 | return new Response(body, { status: 200, headers: { "content-type": "text/html" } })
59 | }
60 |
61 | const handlerRouter = async (req: Request): Promise => {
62 | console.log("handlerRouter", req.url)
63 | if (new URL(req.url).pathname === "/edit") return await handlerEdit(req)
64 | if (new URL(req.url).pathname === "/openai") return await handlerOpenAI(req)
65 | return handlerMainView(req)
66 | }
67 |
68 | const handlerEdit = async (req: Request): Promise => {
69 | console.log("handlerEdit")
70 | if (req.method !== "POST") {
71 | console.warn("Error; Endpoint requires POST")
72 | return new Response("Error; Endpoint requires POST", { status: 400, headers: { "content-type": "text/html" } })
73 | }
74 | if (Deno.build.os !== "darwin") {
75 | console.warn("NOT IMPLEMENTED")
76 | return new Response("NOT IMPLEMENTED", { status: 400, headers: { "content-type": "text/html" } })
77 | } else {
78 | console.log("Opening VSCode…")
79 | const vscode = Deno.run({
80 | cmd: ["/usr/local/bin/code", `${__dirname}/../..`],
81 | stdout: "piped",
82 | stderr: "piped",
83 | })
84 | const { code } = await vscode.status()
85 | console.log("VSCode exited with code", code)
86 | if (code !== 0) {
87 | const rawError = await vscode.stderrOutput()
88 | const errorString = new TextDecoder().decode(rawError)
89 | return new Response(errorString, { status: 500, headers: { "content-type": "text/html" } })
90 | }
91 | return new Response("Done", { status: 200, headers: { "content-type": "text/html" } })
92 | }
93 | }
94 |
95 | async function handlerOpenAI(req: Request): Promise {
96 | console.log("handlerOpenAI")
97 | if (req.method !== "POST") {
98 | console.warn("Error; Endpoint requires POST")
99 | return new Response("Error; Endpoint requires POST", { status: 400, headers: { "content-type": "text/html" } })
100 | }
101 | const body = await req.json()
102 | console.log("body", body)
103 | const response = await fetch("https://api.openai.com/v1/engines/davinci/completions", {
104 | method: "POST",
105 | headers: {
106 | Authorization: `Bearer ${Deno.env.get("OPENAI_API_KEY")}`,
107 | "Content-Type": "application/json",
108 | },
109 | body: JSON.stringify({
110 | prompt: body.prompt,
111 | max_tokens: 5,
112 | temperature: 0.9,
113 | top_p: 1,
114 | frequency_penalty: 0,
115 | presence_penalty: 0,
116 | stop: ["\n"],
117 | }),
118 | })
119 | const json = await response.json()
120 | console.log("json", json)
121 | return new Response(JSON.stringify(json), { status: 200, headers: { "content-type": "application/json" } })
122 | }
123 |
124 | if (import.meta.main) {
125 | console.log("starting webview server…")
126 | webviewServer.create(handlerRouter)
127 | }
128 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Appify UI 2011–2024
2 |
3 | Create Mac apps.
4 | Use HTML5 for the UI.
5 | Script it with anything.
6 | Can not possibly be simpler.
7 | This is dumb and bad and old.
8 | You should not use this.
9 |
10 | But after a decade or so, I still use this thing and it works great for me.
11 |
12 | ## New in 2023: rebuilt Appify UI native innards
13 |
14 | Back in 2023, I recreated the native innards of Appify UI using Swift and SwiftUI.
15 |
16 | ---
17 |
18 | ## What is this?
19 |
20 | A Mac app is essentially just an executable file in a folder along with a config file.
21 | That's all that is required.
22 |
23 | An Appify UI app is
24 |
25 | 1. A folder structure
26 | - That conforms to the Cocoa Application Bundle standard
27 | 2. A config file
28 | 3. A shell script
29 | 4. A compiled binary
30 | - To load the interface
31 | 5. An interface
32 | - A compiled nib file with a single WebKit WebView
33 | 6. A url
34 |
35 | ## Appify UI.app
36 |
37 | A shell script that accepts arguments from an HTML form.
38 |
39 | It creates a new Appify UI app on your Desktop with the configuration you provide.
40 |
41 | The UI could be a lot better. Pull requests eagerly accepted.
42 |
43 | ## Appify UI Node Demo.app
44 |
45 | Instead of just a bash script, this uses node.js.
46 | If `node` is not found, it quits and opens the node.js download page in your default web browser.
47 | Before launching the webview, it starts up an http server.
48 | When the app is closed, it closes the http server.
49 |
50 | To create your own node.js based Mac app...
51 |
52 | 1. Duplicate `Appify UI Node Demo.app` and give it whatever name you like
53 | - e.g. `My Awesome App.app`
54 | 2. Edit `My Awesome App.app/Contents/Info.plist`
55 | - Each app needs a unique `CFBundleIdentifier` or else _Bad Things_ may happen
56 | 3. Replace the folder `My Awesome App.app/Contents/Resources/app` with your own node.js app
57 | 4. Make sure that `My Awesome App.app/Contents/Resources/app/server.js` exports something with a `listen` method
58 |
59 | ### How to package a Node.js Mac app for distribution
60 |
61 | You could send it around as-is. By default it'll open their web browser and prompt them to install node.js if it's not already installed.
62 |
63 | You could probly also package the `node` binary in the app. I haven't tried this, so please update this README once you do.
64 |
65 | ## How to modify the `nib` and cocoa binary
66 |
67 | The current version uses a heavily modified version of Apache Callback Mac (formerly PhoneGap-mac / MacGap).
68 | It's about as simple as you can get.
69 |
70 | I may update this section later.
71 |
72 | ## Similar Projects
73 |
74 | https://github.com/maccman/macgap is probably what you should be using.
75 |
76 | https://github.com/rogerwang/node-webkit is awesome, but large.
77 |
78 | https://github.com/sveinbjornt/Platypus makes an app from terminal script, wraps it's output in the GUI window, handles `CMD`+`Q` etc
79 |
--------------------------------------------------------------------------------
/github.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E25DD81B29DC8EF200087910 /* Appify_UI_23App.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DD81A29DC8EF200087910 /* Appify_UI_23App.swift */; };
11 | E25DD81D29DC8EF200087910 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DD81C29DC8EF200087910 /* ContentView.swift */; };
12 | E25DD81F29DC8EF300087910 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E25DD81E29DC8EF300087910 /* Assets.xcassets */; };
13 | E25DD82229DC8EF300087910 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E25DD82129DC8EF300087910 /* Preview Assets.xcassets */; };
14 | E25DD82D29DC8EF300087910 /* Appify_UI_23Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DD82C29DC8EF300087910 /* Appify_UI_23Tests.swift */; };
15 | E25DD83729DC8EF300087910 /* Appify_UI_23UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DD83629DC8EF300087910 /* Appify_UI_23UITests.swift */; };
16 | E25DD83929DC8EF300087910 /* Appify_UI_23UITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E25DD83829DC8EF300087910 /* Appify_UI_23UITestsLaunchTests.swift */; };
17 | E25DD84729DC99F700087910 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E25DD84629DC99F700087910 /* WebKit.framework */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | E25DD82929DC8EF300087910 /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = E25DD80F29DC8EF100087910 /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = E25DD81629DC8EF100087910;
26 | remoteInfo = "Appify UI 23";
27 | };
28 | E25DD83329DC8EF300087910 /* PBXContainerItemProxy */ = {
29 | isa = PBXContainerItemProxy;
30 | containerPortal = E25DD80F29DC8EF100087910 /* Project object */;
31 | proxyType = 1;
32 | remoteGlobalIDString = E25DD81629DC8EF100087910;
33 | remoteInfo = "Appify UI 23";
34 | };
35 | /* End PBXContainerItemProxy section */
36 |
37 | /* Begin PBXFileReference section */
38 | E25DD81729DC8EF200087910 /* Appify UI 23.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Appify UI 23.app"; sourceTree = BUILT_PRODUCTS_DIR; };
39 | E25DD81A29DC8EF200087910 /* Appify_UI_23App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appify_UI_23App.swift; sourceTree = ""; };
40 | E25DD81C29DC8EF200087910 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
41 | E25DD81E29DC8EF300087910 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
42 | E25DD82129DC8EF300087910 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
43 | E25DD82329DC8EF300087910 /* Appify_UI_23.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Appify_UI_23.entitlements; sourceTree = ""; };
44 | E25DD82829DC8EF300087910 /* Appify UI 23Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Appify UI 23Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
45 | E25DD82C29DC8EF300087910 /* Appify_UI_23Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appify_UI_23Tests.swift; sourceTree = ""; };
46 | E25DD83229DC8EF300087910 /* Appify UI 23UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Appify UI 23UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
47 | E25DD83629DC8EF300087910 /* Appify_UI_23UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appify_UI_23UITests.swift; sourceTree = ""; };
48 | E25DD83829DC8EF300087910 /* Appify_UI_23UITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appify_UI_23UITestsLaunchTests.swift; sourceTree = ""; };
49 | E25DD84629DC99F700087910 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
50 | E25DD84829DCABCA00087910 /* Appify-UI-23-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Appify-UI-23-Info.plist"; sourceTree = SOURCE_ROOT; };
51 | /* End PBXFileReference section */
52 |
53 | /* Begin PBXFrameworksBuildPhase section */
54 | E25DD81429DC8EF100087910 /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | E25DD84729DC99F700087910 /* WebKit.framework in Frameworks */,
59 | );
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | E25DD82529DC8EF300087910 /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | E25DD82F29DC8EF300087910 /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | /* End PBXFrameworksBuildPhase section */
77 |
78 | /* Begin PBXGroup section */
79 | E25DD80E29DC8EF100087910 = {
80 | isa = PBXGroup;
81 | children = (
82 | E25DD81929DC8EF200087910 /* Appify UI 23 */,
83 | E25DD82B29DC8EF300087910 /* Appify UI 23Tests */,
84 | E25DD83529DC8EF300087910 /* Appify UI 23UITests */,
85 | E25DD81829DC8EF200087910 /* Products */,
86 | E25DD84529DC99F700087910 /* Frameworks */,
87 | );
88 | sourceTree = "";
89 | };
90 | E25DD81829DC8EF200087910 /* Products */ = {
91 | isa = PBXGroup;
92 | children = (
93 | E25DD81729DC8EF200087910 /* Appify UI 23.app */,
94 | E25DD82829DC8EF300087910 /* Appify UI 23Tests.xctest */,
95 | E25DD83229DC8EF300087910 /* Appify UI 23UITests.xctest */,
96 | );
97 | name = Products;
98 | sourceTree = "";
99 | };
100 | E25DD81929DC8EF200087910 /* Appify UI 23 */ = {
101 | isa = PBXGroup;
102 | children = (
103 | E25DD84829DCABCA00087910 /* Appify-UI-23-Info.plist */,
104 | E25DD81A29DC8EF200087910 /* Appify_UI_23App.swift */,
105 | E25DD81C29DC8EF200087910 /* ContentView.swift */,
106 | E25DD81E29DC8EF300087910 /* Assets.xcassets */,
107 | E25DD82329DC8EF300087910 /* Appify_UI_23.entitlements */,
108 | E25DD82029DC8EF300087910 /* Preview Content */,
109 | );
110 | path = "Appify UI 23";
111 | sourceTree = "";
112 | };
113 | E25DD82029DC8EF300087910 /* Preview Content */ = {
114 | isa = PBXGroup;
115 | children = (
116 | E25DD82129DC8EF300087910 /* Preview Assets.xcassets */,
117 | );
118 | path = "Preview Content";
119 | sourceTree = "";
120 | };
121 | E25DD82B29DC8EF300087910 /* Appify UI 23Tests */ = {
122 | isa = PBXGroup;
123 | children = (
124 | E25DD82C29DC8EF300087910 /* Appify_UI_23Tests.swift */,
125 | );
126 | path = "Appify UI 23Tests";
127 | sourceTree = "";
128 | };
129 | E25DD83529DC8EF300087910 /* Appify UI 23UITests */ = {
130 | isa = PBXGroup;
131 | children = (
132 | E25DD83629DC8EF300087910 /* Appify_UI_23UITests.swift */,
133 | E25DD83829DC8EF300087910 /* Appify_UI_23UITestsLaunchTests.swift */,
134 | );
135 | path = "Appify UI 23UITests";
136 | sourceTree = "";
137 | };
138 | E25DD84529DC99F700087910 /* Frameworks */ = {
139 | isa = PBXGroup;
140 | children = (
141 | E25DD84629DC99F700087910 /* WebKit.framework */,
142 | );
143 | name = Frameworks;
144 | sourceTree = "";
145 | };
146 | /* End PBXGroup section */
147 |
148 | /* Begin PBXNativeTarget section */
149 | E25DD81629DC8EF100087910 /* Appify UI 23 */ = {
150 | isa = PBXNativeTarget;
151 | buildConfigurationList = E25DD83C29DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23" */;
152 | buildPhases = (
153 | E25DD81329DC8EF100087910 /* Sources */,
154 | E25DD81429DC8EF100087910 /* Frameworks */,
155 | E25DD81529DC8EF100087910 /* Resources */,
156 | );
157 | buildRules = (
158 | );
159 | dependencies = (
160 | );
161 | name = "Appify UI 23";
162 | productName = "Appify UI 23";
163 | productReference = E25DD81729DC8EF200087910 /* Appify UI 23.app */;
164 | productType = "com.apple.product-type.application";
165 | };
166 | E25DD82729DC8EF300087910 /* Appify UI 23Tests */ = {
167 | isa = PBXNativeTarget;
168 | buildConfigurationList = E25DD83F29DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23Tests" */;
169 | buildPhases = (
170 | E25DD82429DC8EF300087910 /* Sources */,
171 | E25DD82529DC8EF300087910 /* Frameworks */,
172 | E25DD82629DC8EF300087910 /* Resources */,
173 | );
174 | buildRules = (
175 | );
176 | dependencies = (
177 | E25DD82A29DC8EF300087910 /* PBXTargetDependency */,
178 | );
179 | name = "Appify UI 23Tests";
180 | productName = "Appify UI 23Tests";
181 | productReference = E25DD82829DC8EF300087910 /* Appify UI 23Tests.xctest */;
182 | productType = "com.apple.product-type.bundle.unit-test";
183 | };
184 | E25DD83129DC8EF300087910 /* Appify UI 23UITests */ = {
185 | isa = PBXNativeTarget;
186 | buildConfigurationList = E25DD84229DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23UITests" */;
187 | buildPhases = (
188 | E25DD82E29DC8EF300087910 /* Sources */,
189 | E25DD82F29DC8EF300087910 /* Frameworks */,
190 | E25DD83029DC8EF300087910 /* Resources */,
191 | );
192 | buildRules = (
193 | );
194 | dependencies = (
195 | E25DD83429DC8EF300087910 /* PBXTargetDependency */,
196 | );
197 | name = "Appify UI 23UITests";
198 | productName = "Appify UI 23UITests";
199 | productReference = E25DD83229DC8EF300087910 /* Appify UI 23UITests.xctest */;
200 | productType = "com.apple.product-type.bundle.ui-testing";
201 | };
202 | /* End PBXNativeTarget section */
203 |
204 | /* Begin PBXProject section */
205 | E25DD80F29DC8EF100087910 /* Project object */ = {
206 | isa = PBXProject;
207 | attributes = {
208 | BuildIndependentTargetsInParallel = 1;
209 | LastSwiftUpdateCheck = 1430;
210 | LastUpgradeCheck = 1430;
211 | TargetAttributes = {
212 | E25DD81629DC8EF100087910 = {
213 | CreatedOnToolsVersion = 14.3;
214 | };
215 | E25DD82729DC8EF300087910 = {
216 | CreatedOnToolsVersion = 14.3;
217 | TestTargetID = E25DD81629DC8EF100087910;
218 | };
219 | E25DD83129DC8EF300087910 = {
220 | CreatedOnToolsVersion = 14.3;
221 | TestTargetID = E25DD81629DC8EF100087910;
222 | };
223 | };
224 | };
225 | buildConfigurationList = E25DD81229DC8EF100087910 /* Build configuration list for PBXProject "Appify UI 23" */;
226 | compatibilityVersion = "Xcode 14.0";
227 | developmentRegion = en;
228 | hasScannedForEncodings = 0;
229 | knownRegions = (
230 | en,
231 | Base,
232 | );
233 | mainGroup = E25DD80E29DC8EF100087910;
234 | productRefGroup = E25DD81829DC8EF200087910 /* Products */;
235 | projectDirPath = "";
236 | projectRoot = "";
237 | targets = (
238 | E25DD81629DC8EF100087910 /* Appify UI 23 */,
239 | E25DD82729DC8EF300087910 /* Appify UI 23Tests */,
240 | E25DD83129DC8EF300087910 /* Appify UI 23UITests */,
241 | );
242 | };
243 | /* End PBXProject section */
244 |
245 | /* Begin PBXResourcesBuildPhase section */
246 | E25DD81529DC8EF100087910 /* Resources */ = {
247 | isa = PBXResourcesBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | E25DD82229DC8EF300087910 /* Preview Assets.xcassets in Resources */,
251 | E25DD81F29DC8EF300087910 /* Assets.xcassets in Resources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | E25DD82629DC8EF300087910 /* Resources */ = {
256 | isa = PBXResourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | };
262 | E25DD83029DC8EF300087910 /* Resources */ = {
263 | isa = PBXResourcesBuildPhase;
264 | buildActionMask = 2147483647;
265 | files = (
266 | );
267 | runOnlyForDeploymentPostprocessing = 0;
268 | };
269 | /* End PBXResourcesBuildPhase section */
270 |
271 | /* Begin PBXSourcesBuildPhase section */
272 | E25DD81329DC8EF100087910 /* Sources */ = {
273 | isa = PBXSourcesBuildPhase;
274 | buildActionMask = 2147483647;
275 | files = (
276 | E25DD81D29DC8EF200087910 /* ContentView.swift in Sources */,
277 | E25DD81B29DC8EF200087910 /* Appify_UI_23App.swift in Sources */,
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | };
281 | E25DD82429DC8EF300087910 /* Sources */ = {
282 | isa = PBXSourcesBuildPhase;
283 | buildActionMask = 2147483647;
284 | files = (
285 | E25DD82D29DC8EF300087910 /* Appify_UI_23Tests.swift in Sources */,
286 | );
287 | runOnlyForDeploymentPostprocessing = 0;
288 | };
289 | E25DD82E29DC8EF300087910 /* Sources */ = {
290 | isa = PBXSourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | E25DD83929DC8EF300087910 /* Appify_UI_23UITestsLaunchTests.swift in Sources */,
294 | E25DD83729DC8EF300087910 /* Appify_UI_23UITests.swift in Sources */,
295 | );
296 | runOnlyForDeploymentPostprocessing = 0;
297 | };
298 | /* End PBXSourcesBuildPhase section */
299 |
300 | /* Begin PBXTargetDependency section */
301 | E25DD82A29DC8EF300087910 /* PBXTargetDependency */ = {
302 | isa = PBXTargetDependency;
303 | target = E25DD81629DC8EF100087910 /* Appify UI 23 */;
304 | targetProxy = E25DD82929DC8EF300087910 /* PBXContainerItemProxy */;
305 | };
306 | E25DD83429DC8EF300087910 /* PBXTargetDependency */ = {
307 | isa = PBXTargetDependency;
308 | target = E25DD81629DC8EF100087910 /* Appify UI 23 */;
309 | targetProxy = E25DD83329DC8EF300087910 /* PBXContainerItemProxy */;
310 | };
311 | /* End PBXTargetDependency section */
312 |
313 | /* Begin XCBuildConfiguration section */
314 | E25DD83A29DC8EF300087910 /* Debug */ = {
315 | isa = XCBuildConfiguration;
316 | buildSettings = {
317 | ALWAYS_SEARCH_USER_PATHS = NO;
318 | CLANG_ANALYZER_NONNULL = YES;
319 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
321 | CLANG_ENABLE_MODULES = YES;
322 | CLANG_ENABLE_OBJC_ARC = YES;
323 | CLANG_ENABLE_OBJC_WEAK = YES;
324 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
325 | CLANG_WARN_BOOL_CONVERSION = YES;
326 | CLANG_WARN_COMMA = YES;
327 | CLANG_WARN_CONSTANT_CONVERSION = YES;
328 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
329 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
330 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
331 | CLANG_WARN_EMPTY_BODY = YES;
332 | CLANG_WARN_ENUM_CONVERSION = YES;
333 | CLANG_WARN_INFINITE_RECURSION = YES;
334 | CLANG_WARN_INT_CONVERSION = YES;
335 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
336 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
337 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
339 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
340 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
341 | CLANG_WARN_STRICT_PROTOTYPES = YES;
342 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
343 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
344 | CLANG_WARN_UNREACHABLE_CODE = YES;
345 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
346 | COPY_PHASE_STRIP = NO;
347 | DEBUG_INFORMATION_FORMAT = dwarf;
348 | ENABLE_STRICT_OBJC_MSGSEND = YES;
349 | ENABLE_TESTABILITY = YES;
350 | GCC_C_LANGUAGE_STANDARD = gnu11;
351 | GCC_DYNAMIC_NO_PIC = NO;
352 | GCC_NO_COMMON_BLOCKS = YES;
353 | GCC_OPTIMIZATION_LEVEL = 0;
354 | GCC_PREPROCESSOR_DEFINITIONS = (
355 | "DEBUG=1",
356 | "$(inherited)",
357 | );
358 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
359 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
360 | GCC_WARN_UNDECLARED_SELECTOR = YES;
361 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
362 | GCC_WARN_UNUSED_FUNCTION = YES;
363 | GCC_WARN_UNUSED_VARIABLE = YES;
364 | MACOSX_DEPLOYMENT_TARGET = 13.2;
365 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
366 | MTL_FAST_MATH = YES;
367 | ONLY_ACTIVE_ARCH = YES;
368 | SDKROOT = macosx;
369 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
370 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
371 | };
372 | name = Debug;
373 | };
374 | E25DD83B29DC8EF300087910 /* Release */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | ALWAYS_SEARCH_USER_PATHS = NO;
378 | CLANG_ANALYZER_NONNULL = YES;
379 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
380 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
381 | CLANG_ENABLE_MODULES = YES;
382 | CLANG_ENABLE_OBJC_ARC = YES;
383 | CLANG_ENABLE_OBJC_WEAK = YES;
384 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
385 | CLANG_WARN_BOOL_CONVERSION = YES;
386 | CLANG_WARN_COMMA = YES;
387 | CLANG_WARN_CONSTANT_CONVERSION = YES;
388 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
389 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
390 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
391 | CLANG_WARN_EMPTY_BODY = YES;
392 | CLANG_WARN_ENUM_CONVERSION = YES;
393 | CLANG_WARN_INFINITE_RECURSION = YES;
394 | CLANG_WARN_INT_CONVERSION = YES;
395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
399 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
400 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
401 | CLANG_WARN_STRICT_PROTOTYPES = YES;
402 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
403 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
404 | CLANG_WARN_UNREACHABLE_CODE = YES;
405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
406 | COPY_PHASE_STRIP = NO;
407 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
408 | ENABLE_NS_ASSERTIONS = NO;
409 | ENABLE_STRICT_OBJC_MSGSEND = YES;
410 | GCC_C_LANGUAGE_STANDARD = gnu11;
411 | GCC_NO_COMMON_BLOCKS = YES;
412 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
413 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
414 | GCC_WARN_UNDECLARED_SELECTOR = YES;
415 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
416 | GCC_WARN_UNUSED_FUNCTION = YES;
417 | GCC_WARN_UNUSED_VARIABLE = YES;
418 | MACOSX_DEPLOYMENT_TARGET = 13.2;
419 | MTL_ENABLE_DEBUG_INFO = NO;
420 | MTL_FAST_MATH = YES;
421 | SDKROOT = macosx;
422 | SWIFT_COMPILATION_MODE = wholemodule;
423 | SWIFT_OPTIMIZATION_LEVEL = "-O";
424 | };
425 | name = Release;
426 | };
427 | E25DD83D29DC8EF300087910 /* Debug */ = {
428 | isa = XCBuildConfiguration;
429 | buildSettings = {
430 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
431 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
432 | CODE_SIGN_ENTITLEMENTS = "Appify UI 23/Appify_UI_23.entitlements";
433 | CODE_SIGN_STYLE = Automatic;
434 | COMBINE_HIDPI_IMAGES = YES;
435 | CURRENT_PROJECT_VERSION = 1;
436 | DEVELOPMENT_ASSET_PATHS = "\"Appify UI 23/Preview Content\"";
437 | ENABLE_PREVIEWS = YES;
438 | GENERATE_INFOPLIST_FILE = YES;
439 | INFOPLIST_FILE = "Appify-UI-23-Info.plist";
440 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
441 | LD_RUNPATH_SEARCH_PATHS = (
442 | "$(inherited)",
443 | "@executable_path/../Frameworks",
444 | );
445 | MARKETING_VERSION = 1.0;
446 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23";
447 | PRODUCT_NAME = "$(TARGET_NAME)";
448 | SWIFT_EMIT_LOC_STRINGS = YES;
449 | SWIFT_VERSION = 5.0;
450 | };
451 | name = Debug;
452 | };
453 | E25DD83E29DC8EF300087910 /* Release */ = {
454 | isa = XCBuildConfiguration;
455 | buildSettings = {
456 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
457 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
458 | CODE_SIGN_ENTITLEMENTS = "Appify UI 23/Appify_UI_23.entitlements";
459 | CODE_SIGN_STYLE = Automatic;
460 | COMBINE_HIDPI_IMAGES = YES;
461 | CURRENT_PROJECT_VERSION = 1;
462 | DEVELOPMENT_ASSET_PATHS = "\"Appify UI 23/Preview Content\"";
463 | ENABLE_PREVIEWS = YES;
464 | GENERATE_INFOPLIST_FILE = YES;
465 | INFOPLIST_FILE = "Appify-UI-23-Info.plist";
466 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
467 | LD_RUNPATH_SEARCH_PATHS = (
468 | "$(inherited)",
469 | "@executable_path/../Frameworks",
470 | );
471 | MARKETING_VERSION = 1.0;
472 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23";
473 | PRODUCT_NAME = "$(TARGET_NAME)";
474 | SWIFT_EMIT_LOC_STRINGS = YES;
475 | SWIFT_VERSION = 5.0;
476 | };
477 | name = Release;
478 | };
479 | E25DD84029DC8EF300087910 /* Debug */ = {
480 | isa = XCBuildConfiguration;
481 | buildSettings = {
482 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
483 | BUNDLE_LOADER = "$(TEST_HOST)";
484 | CODE_SIGN_STYLE = Automatic;
485 | CURRENT_PROJECT_VERSION = 1;
486 | GENERATE_INFOPLIST_FILE = YES;
487 | MACOSX_DEPLOYMENT_TARGET = 13.2;
488 | MARKETING_VERSION = 1.0;
489 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23Tests";
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | SWIFT_EMIT_LOC_STRINGS = NO;
492 | SWIFT_VERSION = 5.0;
493 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Appify UI 23.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Appify UI 23";
494 | };
495 | name = Debug;
496 | };
497 | E25DD84129DC8EF300087910 /* Release */ = {
498 | isa = XCBuildConfiguration;
499 | buildSettings = {
500 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
501 | BUNDLE_LOADER = "$(TEST_HOST)";
502 | CODE_SIGN_STYLE = Automatic;
503 | CURRENT_PROJECT_VERSION = 1;
504 | GENERATE_INFOPLIST_FILE = YES;
505 | MACOSX_DEPLOYMENT_TARGET = 13.2;
506 | MARKETING_VERSION = 1.0;
507 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23Tests";
508 | PRODUCT_NAME = "$(TARGET_NAME)";
509 | SWIFT_EMIT_LOC_STRINGS = NO;
510 | SWIFT_VERSION = 5.0;
511 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Appify UI 23.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Appify UI 23";
512 | };
513 | name = Release;
514 | };
515 | E25DD84329DC8EF300087910 /* Debug */ = {
516 | isa = XCBuildConfiguration;
517 | buildSettings = {
518 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
519 | CODE_SIGN_STYLE = Automatic;
520 | CURRENT_PROJECT_VERSION = 1;
521 | GENERATE_INFOPLIST_FILE = YES;
522 | MARKETING_VERSION = 1.0;
523 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23UITests";
524 | PRODUCT_NAME = "$(TARGET_NAME)";
525 | SWIFT_EMIT_LOC_STRINGS = NO;
526 | SWIFT_VERSION = 5.0;
527 | TEST_TARGET_NAME = "Appify UI 23";
528 | };
529 | name = Debug;
530 | };
531 | E25DD84429DC8EF300087910 /* Release */ = {
532 | isa = XCBuildConfiguration;
533 | buildSettings = {
534 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
535 | CODE_SIGN_STYLE = Automatic;
536 | CURRENT_PROJECT_VERSION = 1;
537 | GENERATE_INFOPLIST_FILE = YES;
538 | MARKETING_VERSION = 1.0;
539 | PRODUCT_BUNDLE_IDENTIFIER = "com.ThingsThatDoStuff.Appify-UI-23UITests";
540 | PRODUCT_NAME = "$(TARGET_NAME)";
541 | SWIFT_EMIT_LOC_STRINGS = NO;
542 | SWIFT_VERSION = 5.0;
543 | TEST_TARGET_NAME = "Appify UI 23";
544 | };
545 | name = Release;
546 | };
547 | /* End XCBuildConfiguration section */
548 |
549 | /* Begin XCConfigurationList section */
550 | E25DD81229DC8EF100087910 /* Build configuration list for PBXProject "Appify UI 23" */ = {
551 | isa = XCConfigurationList;
552 | buildConfigurations = (
553 | E25DD83A29DC8EF300087910 /* Debug */,
554 | E25DD83B29DC8EF300087910 /* Release */,
555 | );
556 | defaultConfigurationIsVisible = 0;
557 | defaultConfigurationName = Release;
558 | };
559 | E25DD83C29DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23" */ = {
560 | isa = XCConfigurationList;
561 | buildConfigurations = (
562 | E25DD83D29DC8EF300087910 /* Debug */,
563 | E25DD83E29DC8EF300087910 /* Release */,
564 | );
565 | defaultConfigurationIsVisible = 0;
566 | defaultConfigurationName = Release;
567 | };
568 | E25DD83F29DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23Tests" */ = {
569 | isa = XCConfigurationList;
570 | buildConfigurations = (
571 | E25DD84029DC8EF300087910 /* Debug */,
572 | E25DD84129DC8EF300087910 /* Release */,
573 | );
574 | defaultConfigurationIsVisible = 0;
575 | defaultConfigurationName = Release;
576 | };
577 | E25DD84229DC8EF300087910 /* Build configuration list for PBXNativeTarget "Appify UI 23UITests" */ = {
578 | isa = XCConfigurationList;
579 | buildConfigurations = (
580 | E25DD84329DC8EF300087910 /* Debug */,
581 | E25DD84429DC8EF300087910 /* Release */,
582 | );
583 | defaultConfigurationIsVisible = 0;
584 | defaultConfigurationName = Release;
585 | };
586 | /* End XCConfigurationList section */
587 | };
588 | rootObject = E25DD80F29DC8EF100087910 /* Project object */;
589 | }
590 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/project.xcworkspace/xcuserdata/tom.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/subtleGradient/Appify-UI/9dbfaf521066ca989844f6981d4eb53eda10cae6/source/Appify UI 23/Appify UI 23.xcodeproj/project.xcworkspace/xcuserdata/tom.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/xcuserdata/tom.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23.xcodeproj/xcuserdata/tom.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Appify UI 23.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Appify_UI_23.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 | com.apple.security.network.client
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Appify_UI_23App.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 |
3 | func showHelpMessage() {
4 | let helpMessage = """
5 | Usage: Appify_UI_23 [OPTIONS]
6 |
7 | Options:
8 | -u, --url Start the web browser with the specified URL. If not
9 | specified, the default URL is the local index.html.
10 | -h, --help Show this help message and exit.
11 | """
12 |
13 | print(helpMessage)
14 | }
15 |
16 | func parseCommandLine(_ arguments: [String]) -> URL? {
17 | var specifiedURL: URL?
18 | var skipNext = false
19 | loop: for i in 1..<(arguments.count) {
20 | if skipNext {
21 | skipNext = false
22 | continue
23 | }
24 |
25 | let arg = arguments[i]
26 |
27 | switch arg {
28 | case "-h", "--help":
29 | showHelpMessage()
30 | NSApp.terminate(nil)
31 |
32 | case "-u", "--url":
33 | let nextIndex = i + 1
34 | if nextIndex < arguments.count,
35 | let url = URL(string: arguments[nextIndex]) {
36 | specifiedURL = url
37 | skipNext = true
38 | }
39 |
40 | default:
41 | break loop
42 | }
43 | }
44 |
45 | return specifiedURL
46 | }
47 |
48 | @main
49 | struct Appify_UI_23App: App {
50 | var body: some Scene {
51 | WindowGroup {
52 | let specifiedURL = parseCommandLine(CommandLine.arguments)
53 | let defaultURL = Bundle.main.url(forResource: "index", withExtension: "html") ?? URL(string: "https://double.observer/")!
54 | let url = specifiedURL ?? defaultURL
55 | ContentView(url: url)
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/ContentView.swift:
--------------------------------------------------------------------------------
1 | import SwiftUI
2 | import WebKit
3 |
4 | import SwiftUI
5 | import WebKit
6 |
7 | struct WebView: NSViewRepresentable {
8 |
9 | let url: URL
10 |
11 | func makeCoordinator() -> Coordinator {
12 | Coordinator(self)
13 | }
14 |
15 | func makeNSView(context: Context) -> WKWebView {
16 | let webView = WKWebView()
17 | webView.navigationDelegate = context.coordinator
18 | return webView
19 | }
20 |
21 | func updateNSView(_ nsView: WKWebView, context: Context) {
22 | nsView.load(URLRequest(url: url))
23 | }
24 |
25 | class Coordinator: NSObject, WKNavigationDelegate {
26 | var parent: WebView
27 |
28 | init(_ parent: WebView) {
29 | self.parent = parent
30 | }
31 | }
32 | }
33 |
34 | struct ContentView: View {
35 | let url: URL
36 |
37 | var body: some View {
38 | WebView(url: url)
39 | .frame(minWidth: 200, minHeight: 100)
40 | .edgesIgnoringSafeArea(.all)
41 | }
42 | }
43 |
44 | struct ContentView_Previews: PreviewProvider {
45 | static var previews: some View {
46 | ContentView(url: URL(string: "https://double.observer/")!)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify UI 23/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/Appify UI 23/Appify-UI-23-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/upgrade.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # lol, hard-coded paths
3 |
4 | cd "$(dirname "$0")"
5 |
6 | for bin_path in *.app/Contents/MacOS/apache-callback-mac; do
7 | mv "$bin_path" "$bin_path.old"
8 | cp "$(ls $HOME/Library/Developer/Xcode/DerivedData/callback-mac-*/Build/Products/Debug/Callback.app/Contents/MacOS/Callback)" "$bin_path"
9 | done
10 |
11 | for bin_path in *.app/Contents/MacOS/apache-callback-mac.old; do
12 | if [[ -f "${bin_path/\.old/}" ]]; then
13 | rm "$bin_path"
14 | else
15 | mv "$bin_path" "${bin_path/\.old/}"
16 | fi
17 | done
18 |
19 | for nib_path in *.app/Contents/Resources/English.lproj/MainMenu.nib; do
20 | mv "$nib_path" "$nib_path.old"
21 | cp "$(ls $HOME/Library/Developer/Xcode/DerivedData/callback-mac-*/Build/Products/Debug/Callback.app/Contents/Resources/English.lproj/MainMenu.nib)" "$nib_path"
22 | done
23 |
24 | for nib_path in *.app/Contents/Resources/English.lproj/MainMenu.nib.old; do
25 | if [[ -f "${nib_path/\.old/}" ]]; then
26 | rm "$nib_path"
27 | else
28 | mv "$nib_path" "${nib_path/\.old/}"
29 | fi
30 | done
31 |
--------------------------------------------------------------------------------