├── .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 |
32 | 33 | 34 | 35 |
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 |       
    Don't
    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 | 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 |
    50 | 51 |

    52 | 53 |

    54 | 55 |

    56 | 57 |

    58 | 59 |

    60 | 61 |

    Marketing version number for users to see.

    62 | 63 |

    Launch Services expects the following format: nnnnn[.nn[.nn]][X] where n is a digit 0-9, square brackets indicate optional components, and X is any string not starting with a digit. X is ignored when present.

    64 | 65 |
    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 | --------------------------------------------------------------------------------