Compare commits
67 Commits
c09b08a474
...
1.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bb544e96c | ||
|
|
a104b43b24 | ||
|
|
8d5a63b262 | ||
| 14c885a60f | |||
| 422e89caee | |||
| d0df371a3c | |||
|
|
a1803a6f4a | ||
|
|
3fe1386415 | ||
| a306f0732c | |||
| 027ae4d130 | |||
|
|
2592137fa3 | ||
|
|
8279a81dc9 | ||
|
|
2faa9e740e | ||
|
|
a589977015 | ||
|
|
06e2fabe81 | ||
|
|
d107d68bcc | ||
|
|
472e69d3c0 | ||
| 1c61a4d202 | |||
| 40b0855ca5 | |||
| 124066da59 | |||
|
|
f3aceb69af | ||
|
|
a87d521a4f | ||
|
|
c5b71add07 | ||
|
|
881c9408b6 | ||
|
|
35f0fe3654 | ||
|
|
21b7b0a252 | ||
|
|
1c6f12c210 | ||
| 56f7c7d3a3 | |||
| c7ddb02ac1 | |||
| 63fbab34ce | |||
|
|
8fad5d7717 | ||
|
|
41a9c9d269 | ||
| dd1ec2c374 | |||
| 58589c56dd | |||
|
|
8dd2312aa0 | ||
|
|
5a56dfa051 | ||
| 3a5214ed45 | |||
| 72f0518f9d | |||
| ede464fb0d | |||
| 2082e0c7bc | |||
|
|
d1e4814593 | ||
|
|
530ea7da89 | ||
|
|
5903bafee5 | ||
| 8452841460 | |||
|
|
69b359d9a1 | ||
|
|
a626abe1c3 | ||
| 834d5e763e | |||
| dde27f9b31 | |||
| 0d5e68188d | |||
|
|
fc2d9c2bc9 | ||
| cb11d68fa7 | |||
|
|
07f431e2a3 | ||
| e85ffc66f8 | |||
|
|
cc8b5035fe | ||
|
|
83a640433a | ||
|
|
cee8ebecc5 | ||
|
|
f02f181058 | ||
|
|
4432acfea5 | ||
|
|
9d0149de75 | ||
|
|
e548dbb6c9 | ||
| 770d3bb012 | |||
|
|
3bf23daa7a | ||
|
|
6cbb4c8dad | ||
| b20ce6da06 | |||
| a68f35faf5 | |||
|
|
6262ce53aa | ||
|
|
6d50337e3b |
1
.gitignore
vendored
@@ -5,3 +5,4 @@ node_modules/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.sourcemaps
|
.sourcemaps
|
||||||
dist/
|
dist/
|
||||||
|
package-lock.json
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"appId": "so.blockcatcher.app",
|
"appId": "so.forum.app",
|
||||||
"appName": "Blockcatcher",
|
"appName": "Forum",
|
||||||
"webDir": "dist",
|
"webDir": "dist",
|
||||||
|
"ios": {
|
||||||
|
"allowsBackForwardNavigationGestures": true
|
||||||
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"SplashScreen": {
|
"SplashScreen": {
|
||||||
"launchAutoHide": false
|
"launchAutoHide": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
158
doc.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
|
||||||
|
Quill is a SwiftUI-style JavaScript framework. It makes use of components called Shadows, which are HTML Custom Elements.
|
||||||
|
|
||||||
|
### Getting Started:
|
||||||
|
Take index.js and put it in your app. Typically as quill.js. Then import it in the head of the HTML.
|
||||||
|
|
||||||
|
### Basic Overview:
|
||||||
|
|
||||||
|
Quill uses components called Shadows. Each Shadow is a Custom HTML Element (https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements)
|
||||||
|
```
|
||||||
|
class Home extends Shadow {
|
||||||
|
render() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(Home)
|
||||||
|
```
|
||||||
|
|
||||||
|
Once created, it can be imported like
|
||||||
|
```
|
||||||
|
import "Home.js"
|
||||||
|
```
|
||||||
|
(Not how we are NOT importing the actual class object. If that happens, it will fail.)
|
||||||
|
|
||||||
|
Here is an example of Hello World:
|
||||||
|
|
||||||
|
```
|
||||||
|
class Home extends Shadow {
|
||||||
|
render() {
|
||||||
|
p("Hello World")
|
||||||
|
.x(50, vw)
|
||||||
|
.y(50, vh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(Home)
|
||||||
|
```
|
||||||
|
|
||||||
|
This will render a paragraph tag in the middle of the screen.
|
||||||
|
|
||||||
|
Here's what it will look like in HTML:
|
||||||
|
|
||||||
|
```
|
||||||
|
<body>
|
||||||
|
<home->
|
||||||
|
<p style="position: absolute; top: 50vh; left: 50vw;">Hello World</p>
|
||||||
|
</home->
|
||||||
|
</body>
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: .x() and .y() are quill-specific functions that were created simply for nice syntax. However, this would also be valid:
|
||||||
|
```
|
||||||
|
p("Hello World")
|
||||||
|
.top(50, vh)
|
||||||
|
.left(50, vw)
|
||||||
|
```
|
||||||
|
|
||||||
|
There are quill functions for every HTML style attribute. If they have units, they will follow the pattern directly above, where the first parameter is the amount and the second parameter is the unit.
|
||||||
|
|
||||||
|
### Real Basic Example:
|
||||||
|
|
||||||
|
First, you need your index.html. Here is one:
|
||||||
|
|
||||||
|
```
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" class="public">
|
||||||
|
<head>
|
||||||
|
<title>Parchment</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="/_/icons/quill.svg">
|
||||||
|
<link rel="stylesheet" href="/_/code/shared.css">
|
||||||
|
<script src="/_/code/quill.js"></script>
|
||||||
|
<script type="module" src="75820185/index.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
When starting, it is typical to make a "Home" shadow and import it in index.js. Here is an example:
|
||||||
|
|
||||||
|
index.js:
|
||||||
|
```
|
||||||
|
import "./Home.js"
|
||||||
|
Home()
|
||||||
|
```
|
||||||
|
|
||||||
|
Home.js:
|
||||||
|
```
|
||||||
|
import "../components/NavBar.js"
|
||||||
|
import "./HomeContent.js"
|
||||||
|
import "./Why.js"
|
||||||
|
import "./Events.js"
|
||||||
|
import "./Join.js"
|
||||||
|
import "./SignIn.js"
|
||||||
|
import "./Success.js"
|
||||||
|
|
||||||
|
class Home extends Shadow {
|
||||||
|
render() {
|
||||||
|
|
||||||
|
ZStack(() => {
|
||||||
|
|
||||||
|
NavBar()
|
||||||
|
|
||||||
|
img("/_/icons/logo.svg", "2.5em")
|
||||||
|
.onClick((done) => {
|
||||||
|
if(!done) return
|
||||||
|
window.navigateTo("/")
|
||||||
|
})
|
||||||
|
.position("absolute")
|
||||||
|
.left(50, vw).top(4, em)
|
||||||
|
.center()
|
||||||
|
.transform(`translate(${window.isMobile() ? "-50%" : "-2em"}, -50%)`)
|
||||||
|
|
||||||
|
switch(window.location.pathname) {
|
||||||
|
case "/":
|
||||||
|
HomeContent()
|
||||||
|
break;
|
||||||
|
case "/why":
|
||||||
|
Why()
|
||||||
|
break;
|
||||||
|
case "/events":
|
||||||
|
Events()
|
||||||
|
break;
|
||||||
|
case "/join":
|
||||||
|
Join()
|
||||||
|
break;
|
||||||
|
case "/success":
|
||||||
|
Success()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.onNavigate(() => {
|
||||||
|
this.rerender()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(Home)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Success.js:
|
||||||
|
|
||||||
|
```
|
||||||
|
class Success extends Shadow {
|
||||||
|
render() {
|
||||||
|
p("Thanks for your purchase! You will receive a confirmation email shortly. <br><br> <b>Keep that email; it will be checked at the door.</b>")
|
||||||
|
.x(50, vw).y(50, vh)
|
||||||
|
.center()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register(Success)
|
||||||
|
```
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
22352DD22F74F93C0052EF07 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = "<group>"; };
|
||||||
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = "<group>"; };
|
||||||
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = "<group>"; };
|
||||||
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@@ -73,6 +74,7 @@
|
|||||||
504EC3061FED79650016851F /* App */ = {
|
504EC3061FED79650016851F /* App */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
22352DD22F74F93C0052EF07 /* App.entitlements */,
|
||||||
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
50379B222058CBB4000EE86E /* capacitor.config.json */,
|
||||||
504EC3071FED79650016851F /* AppDelegate.swift */,
|
504EC3071FED79650016851F /* AppDelegate.swift */,
|
||||||
504EC30B1FED79650016851F /* Main.storyboard */,
|
504EC30B1FED79650016851F /* Main.storyboard */,
|
||||||
@@ -361,15 +363,16 @@
|
|||||||
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
||||||
INFOPLIST_FILE = App/Info.plist;
|
INFOPLIST_FILE = App/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.6;
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app;
|
PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -382,14 +385,15 @@
|
|||||||
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = App/App.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
||||||
INFOPLIST_FILE = App/Info.plist;
|
INFOPLIST_FILE = App/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app;
|
PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
78
ios/App/App.xcodeproj/xcshareddata/xcschemes/App.xcscheme
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1640"
|
||||||
|
version = "1.7">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES"
|
||||||
|
buildArchitectures = "Automatic">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "504EC3031FED79650016851F"
|
||||||
|
BuildableName = "App.app"
|
||||||
|
BlueprintName = "App"
|
||||||
|
ReferencedContainer = "container:App.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
shouldAutocreateTestPlan = "YES">
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "504EC3031FED79650016851F"
|
||||||
|
BuildableName = "App.app"
|
||||||
|
BlueprintName = "App"
|
||||||
|
ReferencedContainer = "container:App.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "504EC3031FED79650016851F"
|
||||||
|
BuildableName = "App.app"
|
||||||
|
BlueprintName = "App"
|
||||||
|
ReferencedContainer = "container:App.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
8
ios/App/App/App.entitlements
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>aps-environment</key>
|
||||||
|
<string>development</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -7,10 +7,38 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||||
|
self.enableInteractiveKeyboard()
|
||||||
|
}
|
||||||
// Override point for customization after application launch.
|
// Override point for customization after application launch.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enableInteractiveKeyboard() {
|
||||||
|
guard let window = UIApplication.shared.windows.first,
|
||||||
|
let rootView = window.rootViewController?.view else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find WKWebView recursively
|
||||||
|
func findWebView(in view: UIView) -> WKWebView? {
|
||||||
|
if let webView = view as? WKWebView {
|
||||||
|
return webView
|
||||||
|
}
|
||||||
|
for subview in view.subviews {
|
||||||
|
if let found = findWebView(in: subview) {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if let webView = findWebView(in: rootView) {
|
||||||
|
webView.scrollView.keyboardDismissMode = .interactive
|
||||||
|
print("✅ Interactive keyboard enabled!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func applicationWillResignActive(_ application: UIApplication) {
|
func applicationWillResignActive(_ application: UIApplication) {
|
||||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||||
@@ -46,4 +74,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
|
NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
||||||
|
NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 108 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "AppIcon-512@2x.png",
|
"filename" : "Group 73 (6).png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
|
|||||||
BIN
ios/App/App/Assets.xcassets/AppIcon.appiconset/Group 73 (6).png
Normal file
|
After Width: | Height: | Size: 34 KiB |
@@ -1,23 +1,23 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
|
"filename" : "Group 74.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"filename" : "splash-2732x2732-2.png",
|
|
||||||
"scale" : "1x"
|
"scale" : "1x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "Group 75.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"filename" : "splash-2732x2732-1.png",
|
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"filename" : "Group 76.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"filename" : "splash-2732x2732.png",
|
|
||||||
"scale" : "3x"
|
"scale" : "3x"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
ios/App/App/Assets.xcassets/Splash.imageset/Group 74.png
vendored
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
ios/App/App/Assets.xcassets/Splash.imageset/Group 75.png
vendored
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
ios/App/App/Assets.xcassets/Splash.imageset/Group 76.png
vendored
Normal file
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB |
@@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Hyperia</string>
|
<string>Forum</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@@ -22,6 +22,23 @@
|
|||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
||||||
|
<string>Used to find keep local information relevant.</string>
|
||||||
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
|
<string>Used to find forums and communities near you</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Access your photos to set a profile picture and share with others</string>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
@@ -30,18 +47,15 @@
|
|||||||
<array>
|
<array>
|
||||||
<string>armv7</string>
|
<string>armv7</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>UIRequiresFullScreen</key>
|
||||||
|
<true/>
|
||||||
<key>UISupportedInterfaceOrientations</key>
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
</array>
|
</array>
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
|||||||
@@ -12,8 +12,12 @@ def capacitor_pods
|
|||||||
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
|
||||||
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
|
||||||
pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera'
|
pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera'
|
||||||
|
pod 'CapacitorFilesystem', :path => '../../node_modules/@capacitor/filesystem'
|
||||||
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
|
pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
|
||||||
pod 'CapacitorGoogleMaps', :path => '../../node_modules/@capacitor/google-maps'
|
pod 'CapacitorGoogleMaps', :path => '../../node_modules/@capacitor/google-maps'
|
||||||
|
pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
|
||||||
|
pod 'CapacitorPreferences', :path => '../../node_modules/@capacitor/preferences'
|
||||||
|
pod 'CapacitorPushNotifications', :path => '../../node_modules/@capacitor/push-notifications'
|
||||||
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ PODS:
|
|||||||
- CapacitorCamera (7.0.2):
|
- CapacitorCamera (7.0.2):
|
||||||
- Capacitor
|
- Capacitor
|
||||||
- CapacitorCordova (7.4.4)
|
- CapacitorCordova (7.4.4)
|
||||||
|
- CapacitorFilesystem (7.1.8):
|
||||||
|
- Capacitor
|
||||||
|
- IONFilesystemLib (~> 1.1.1)
|
||||||
- CapacitorGeolocation (7.1.5):
|
- CapacitorGeolocation (7.1.5):
|
||||||
- Capacitor
|
- Capacitor
|
||||||
- IONGeolocationLib (= 1.0.1)
|
- IONGeolocationLib (= 1.0.1)
|
||||||
@@ -11,6 +14,12 @@ PODS:
|
|||||||
- Capacitor
|
- Capacitor
|
||||||
- Google-Maps-iOS-Utils (~> 5.0)
|
- Google-Maps-iOS-Utils (~> 5.0)
|
||||||
- GoogleMaps (~> 8.4)
|
- GoogleMaps (~> 8.4)
|
||||||
|
- CapacitorHaptics (7.0.3):
|
||||||
|
- Capacitor
|
||||||
|
- CapacitorPreferences (7.0.4):
|
||||||
|
- Capacitor
|
||||||
|
- CapacitorPushNotifications (7.0.6):
|
||||||
|
- Capacitor
|
||||||
- CapacitorSplashScreen (7.0.3):
|
- CapacitorSplashScreen (7.0.3):
|
||||||
- Capacitor
|
- Capacitor
|
||||||
- Google-Maps-iOS-Utils (5.0.0):
|
- Google-Maps-iOS-Utils (5.0.0):
|
||||||
@@ -20,20 +29,26 @@ PODS:
|
|||||||
- GoogleMaps/Base (8.4.0)
|
- GoogleMaps/Base (8.4.0)
|
||||||
- GoogleMaps/Maps (8.4.0):
|
- GoogleMaps/Maps (8.4.0):
|
||||||
- GoogleMaps/Base
|
- GoogleMaps/Base
|
||||||
|
- IONFilesystemLib (1.1.2)
|
||||||
- IONGeolocationLib (1.0.1)
|
- IONGeolocationLib (1.0.1)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- "Capacitor (from `../../node_modules/@capacitor/ios`)"
|
- "Capacitor (from `../../node_modules/@capacitor/ios`)"
|
||||||
- "CapacitorCamera (from `../../node_modules/@capacitor/camera`)"
|
- "CapacitorCamera (from `../../node_modules/@capacitor/camera`)"
|
||||||
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
|
- "CapacitorCordova (from `../../node_modules/@capacitor/ios`)"
|
||||||
|
- "CapacitorFilesystem (from `../../node_modules/@capacitor/filesystem`)"
|
||||||
- "CapacitorGeolocation (from `../../node_modules/@capacitor/geolocation`)"
|
- "CapacitorGeolocation (from `../../node_modules/@capacitor/geolocation`)"
|
||||||
- "CapacitorGoogleMaps (from `../../node_modules/@capacitor/google-maps`)"
|
- "CapacitorGoogleMaps (from `../../node_modules/@capacitor/google-maps`)"
|
||||||
|
- "CapacitorHaptics (from `../../node_modules/@capacitor/haptics`)"
|
||||||
|
- "CapacitorPreferences (from `../../node_modules/@capacitor/preferences`)"
|
||||||
|
- "CapacitorPushNotifications (from `../../node_modules/@capacitor/push-notifications`)"
|
||||||
- "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)"
|
- "CapacitorSplashScreen (from `../../node_modules/@capacitor/splash-screen`)"
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- Google-Maps-iOS-Utils
|
- Google-Maps-iOS-Utils
|
||||||
- GoogleMaps
|
- GoogleMaps
|
||||||
|
- IONFilesystemLib
|
||||||
- IONGeolocationLib
|
- IONGeolocationLib
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@@ -43,10 +58,18 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../../node_modules/@capacitor/camera"
|
:path: "../../node_modules/@capacitor/camera"
|
||||||
CapacitorCordova:
|
CapacitorCordova:
|
||||||
:path: "../../node_modules/@capacitor/ios"
|
:path: "../../node_modules/@capacitor/ios"
|
||||||
|
CapacitorFilesystem:
|
||||||
|
:path: "../../node_modules/@capacitor/filesystem"
|
||||||
CapacitorGeolocation:
|
CapacitorGeolocation:
|
||||||
:path: "../../node_modules/@capacitor/geolocation"
|
:path: "../../node_modules/@capacitor/geolocation"
|
||||||
CapacitorGoogleMaps:
|
CapacitorGoogleMaps:
|
||||||
:path: "../../node_modules/@capacitor/google-maps"
|
:path: "../../node_modules/@capacitor/google-maps"
|
||||||
|
CapacitorHaptics:
|
||||||
|
:path: "../../node_modules/@capacitor/haptics"
|
||||||
|
CapacitorPreferences:
|
||||||
|
:path: "../../node_modules/@capacitor/preferences"
|
||||||
|
CapacitorPushNotifications:
|
||||||
|
:path: "../../node_modules/@capacitor/push-notifications"
|
||||||
CapacitorSplashScreen:
|
CapacitorSplashScreen:
|
||||||
:path: "../../node_modules/@capacitor/splash-screen"
|
:path: "../../node_modules/@capacitor/splash-screen"
|
||||||
|
|
||||||
@@ -54,13 +77,18 @@ SPEC CHECKSUMS:
|
|||||||
Capacitor: 09d9ff8e9618e8c4b3cab2bbee34a17215dd2fef
|
Capacitor: 09d9ff8e9618e8c4b3cab2bbee34a17215dd2fef
|
||||||
CapacitorCamera: 6e18d54c8ab30d7dc7b8cd93d96f9b4f57e9202a
|
CapacitorCamera: 6e18d54c8ab30d7dc7b8cd93d96f9b4f57e9202a
|
||||||
CapacitorCordova: bf648a636f3c153f652d312ae145fb508b6ffced
|
CapacitorCordova: bf648a636f3c153f652d312ae145fb508b6ffced
|
||||||
|
CapacitorFilesystem: f54cd6b76be06fa7ceb219cf313d32e0d626ea87
|
||||||
CapacitorGeolocation: b96474c3259dd4a294227ea8ec19140b1837cceb
|
CapacitorGeolocation: b96474c3259dd4a294227ea8ec19140b1837cceb
|
||||||
CapacitorGoogleMaps: 20b5445a532f80dbb120fa99941fd094bcc88af6
|
CapacitorGoogleMaps: 20b5445a532f80dbb120fa99941fd094bcc88af6
|
||||||
|
CapacitorHaptics: d17da7dd984cae34111b3f097ccd3e21f9feec62
|
||||||
|
CapacitorPreferences: d82a7e3b95fcab43a553268b803356522910d153
|
||||||
|
CapacitorPushNotifications: c6158ba6f3777f281a675aa43e4011e9723e822b
|
||||||
CapacitorSplashScreen: d06ae8804808e9f649a08e7bb7f283c77b688084
|
CapacitorSplashScreen: d06ae8804808e9f649a08e7bb7f283c77b688084
|
||||||
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
Google-Maps-iOS-Utils: 66d6de12be1ce6d3742a54661e7a79cb317a9321
|
||||||
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
GoogleMaps: 8939898920281c649150e0af74aa291c60f2e77d
|
||||||
|
IONFilesystemLib: 21a63377696b2d8fab5632ecfb7d2ac67bddb68a
|
||||||
IONGeolocationLib: 20f9d0248a0b5264511fb57a37e25dd2badf797a
|
IONGeolocationLib: 20f9d0248a0b5264511fb57a37e25dd2badf797a
|
||||||
|
|
||||||
PODFILE CHECKSUM: 1f8c41a3cb5e4540693adb6a47064e328eec261d
|
PODFILE CHECKSUM: 32ad5bbf56056f7ee8d159f9eae42fe03e911a61
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.15.2
|
||||||
|
|||||||
2275
package-lock.json
generated
14
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "capacitor-app",
|
"name": "Forum",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"description": "An Amazing Capacitor App",
|
"description": "An Amazing Capacitor App",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -13,12 +13,16 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/camera": "latest",
|
"@capacitor/camera": "^7.0.2",
|
||||||
"@capacitor/core": "latest",
|
"@capacitor/core": "^7.4.4",
|
||||||
|
"@capacitor/filesystem": "^7.1.8",
|
||||||
"@capacitor/geolocation": "^7.1.5",
|
"@capacitor/geolocation": "^7.1.5",
|
||||||
"@capacitor/google-maps": "^7.2.0",
|
"@capacitor/google-maps": "^7.2.0",
|
||||||
|
"@capacitor/haptics": "^7.0.3",
|
||||||
"@capacitor/ios": "^7.4.4",
|
"@capacitor/ios": "^7.4.4",
|
||||||
"@capacitor/splash-screen": "latest"
|
"@capacitor/preferences": "^7.0.4",
|
||||||
|
"@capacitor/push-notifications": "^7.0.6",
|
||||||
|
"@capacitor/splash-screen": "^7.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "latest",
|
"@capacitor/cli": "latest",
|
||||||
|
|||||||
67
readme.md
@@ -1,29 +1,64 @@
|
|||||||
## Created with Capacitor Create App
|
## Run in Browser
|
||||||
|
|
||||||
This app was created using [`@capacitor/create-app`](https://github.com/ionic-team/create-capacitor-app),
|
```npm run start```
|
||||||
and comes with a very minimal shell for building an app.
|
|
||||||
|
|
||||||
### Running this example
|
### Browser: Dev Frontend and Dev Backend (localhost)
|
||||||
|
This option should be at the top level of capacitor.config.json
|
||||||
|
"server": {
|
||||||
|
"url": "http://sam.local:5173",
|
||||||
|
"cleartext": true
|
||||||
|
},
|
||||||
|
|
||||||
To run the provided example, you can use `npm start` command.
|
### Browser: Prod Frontend and Prod Backend
|
||||||
|
Run:
|
||||||
|
vite build
|
||||||
|
npx serve dist
|
||||||
|
|
||||||
```bash
|
If you need to login again:
|
||||||
npm start
|
run localStorage.clear() in the browser dev tools console and then refresh the page.
|
||||||
```
|
|
||||||
|
|
||||||
### Background Color
|
## Run On Device
|
||||||
|
|
||||||
In src/manifest.json, "#31d53d" refers to the green color which is visible in the background in the web version. This is not visible in the built version.
|
|
||||||
|
|
||||||
### Running iOS
|
|
||||||
https://capacitorjs.com/docs/ios#adding-the-ios-platform
|
https://capacitorjs.com/docs/ios#adding-the-ios-platform
|
||||||
|
|
||||||
|
One-Time Install:
|
||||||
npm install @capacitor/ios
|
npm install @capacitor/ios
|
||||||
npx cap add ios
|
npx cap add ios
|
||||||
|
|
||||||
|
To Open XCode:
|
||||||
npx cap open ios
|
npx cap open ios
|
||||||
|
|
||||||
To Rerun:
|
Run this command to rebuild for iOS
|
||||||
npm run build && npx cap copy ios
|
npm run build && npx cap copy ios
|
||||||
|
|
||||||
### Note
|
If getting black screen:
|
||||||
You need to be in mobile mode in order for the app to work, in the top right corner of dev tools.
|
npx cap sync iOS
|
||||||
|
|
||||||
|
### iOS: Dev Frontend and Dev Backend (localhost)
|
||||||
|
This option should be at the top level of capacitor.config.json
|
||||||
|
"server": {
|
||||||
|
"url": "http://sam.local:5173",
|
||||||
|
"cleartext": true
|
||||||
|
},
|
||||||
|
|
||||||
|
### iOS: Dev Frontend with Prod Backend (frm.so)
|
||||||
|
Add "https://frm.so" to VITE_API_URL in .env.development
|
||||||
|
|
||||||
|
### iOS: Prod Frontend and Prod Backend (frm.so)
|
||||||
|
Remove the "server" object from capacitor.config.
|
||||||
|
|
||||||
|
### Various Commands
|
||||||
|
npx cap config - this will list the full configuration currently being used
|
||||||
|
|
||||||
|
### Architecture
|
||||||
|
|
||||||
|
In Development, API routes are routed using the vite.config.js.
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
Background Color:
|
||||||
|
In src/manifest.json, "#31d53d" refers to the green color which is visible in the background in the web version. This is not visible in the built version.
|
||||||
|
|
||||||
|
Test Push Notifications:
|
||||||
|
https://icloud.developer.apple.com/dashboard/notifications/teams/53DK57C7ZF/app/russell.sam.forum/notifications/create?notificationId=8bb87cf2-9590-4a63-b7e1-e4c7f2a2c879&environment=DEVELOPMENT¬ificationType=push
|
||||||
|
|
||||||
|
Note: Even if built in "production" mode, the tokens will still be considered "development" by Apple until the app is actually deployed
|
||||||
1
src/.env.development
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_URL=http://localhost:10002
|
||||||
1
src/.env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_API_URL=https://frm.so
|
||||||
39
src/Home.js
@@ -1,39 +0,0 @@
|
|||||||
import "./components/Sidebar.js"
|
|
||||||
import "./components/AppMenu.js"
|
|
||||||
import "./apps/Forum/Forum.js"
|
|
||||||
import "./apps/Messages/Messages.js"
|
|
||||||
import "./apps/Jobs/Jobs.js"
|
|
||||||
|
|
||||||
class Home extends Shadow {
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
Sidebar()
|
|
||||||
|
|
||||||
ZStack(() => {
|
|
||||||
switch(window.location.pathname) {
|
|
||||||
case "/":
|
|
||||||
Forum()
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "/messages":
|
|
||||||
Messages()
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "/jobs":
|
|
||||||
Jobs()
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onNavigate(function () {
|
|
||||||
console.log("navigate")
|
|
||||||
this.rerender()
|
|
||||||
})
|
|
||||||
|
|
||||||
AppMenu()
|
|
||||||
})
|
|
||||||
.overflowX("hidden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Home)
|
|
||||||
1207
src/_/code/quill.js
114
src/_/code/shared.css
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
:root {
|
||||||
|
--main: #FFE9C8;
|
||||||
|
--accent: #570b0b;
|
||||||
|
--lightaccent: #760f0f;
|
||||||
|
--darkaccent: #dfc9ac;
|
||||||
|
--text: #340000;
|
||||||
|
--yellow: #f1f3c3;
|
||||||
|
--bone: #fff2e7;
|
||||||
|
--gold: #FEBA7D;
|
||||||
|
--divider: #bb7c36;
|
||||||
|
--green: #0857265c;
|
||||||
|
--red: #ff0000;
|
||||||
|
--quillred: #DE3F3F;
|
||||||
|
--darkred: #6b2c1d;
|
||||||
|
--brown: #812A18;
|
||||||
|
|
||||||
|
--sidebar: #698b6f;
|
||||||
|
--divider: #523636;
|
||||||
|
--lightDivider: #52363681;
|
||||||
|
--darkbrown: #3f0808;
|
||||||
|
--darkgrey: #5c4646;
|
||||||
|
|
||||||
|
--headertext: #433c36e2;
|
||||||
|
--searchbackground: #ffeed8;
|
||||||
|
--loginButton: var(--main);
|
||||||
|
--loginBackground: #d96b6b;
|
||||||
|
|
||||||
|
--home-src: /_/icons/home.svg;
|
||||||
|
--home-selected-src: /_/icons/homelightselected.svg;
|
||||||
|
--people-src: /_/icons/people.svg;
|
||||||
|
--people-selected-src: /_/icons/peoplelightselected.svg;
|
||||||
|
--settings-src: /_/icons/settings.svg;
|
||||||
|
--settings-selected-src: /_/icons/settingslightselected.svg;
|
||||||
|
--events-src: /_/icons/events.svg;
|
||||||
|
--events-selected-src: /_/icons/eventslightselected.svg;
|
||||||
|
--jobs-src: /_/icons/jobs.svg;
|
||||||
|
--jobs-selected-src: /_/icons/jobslightselected.svg;
|
||||||
|
|
||||||
|
--column-src: /_/icons/column2.svg;
|
||||||
|
--nodes-src: /_/icons/nodes.svg;
|
||||||
|
--forum-src: /_/icons/forum.svg;
|
||||||
|
--trash-src: /_/icons/trash.svg;
|
||||||
|
|
||||||
|
--pin-src: /_/icons/pin.svg;
|
||||||
|
--time-src: /_/icons/time.svg;
|
||||||
|
|
||||||
|
--top-inset: env(safe-area-inset-top, 0px);
|
||||||
|
--bottom-inset: env(safe-area-inset-bottom, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--main: #2A150E;
|
||||||
|
--lightaccent: #69413a;
|
||||||
|
--accent: #3D2622;
|
||||||
|
--darkaccent: #240609;
|
||||||
|
--text: #FADFB6;
|
||||||
|
|
||||||
|
--sidebar: #240609;
|
||||||
|
--divider: #523636;
|
||||||
|
--lightDivider: #52363680;
|
||||||
|
--darktext: #62473E;
|
||||||
|
--headertext: #ffd8bb;
|
||||||
|
--darkred: #6b2c1d;
|
||||||
|
--searchbackground: #260F0C;
|
||||||
|
--loginButton: var(--darkaccent);
|
||||||
|
--loginBackground: var(--accent);
|
||||||
|
|
||||||
|
|
||||||
|
--home-src: /_/icons/homelight.svg;
|
||||||
|
--home-selected-src: /_/icons/homelightselected.svg;
|
||||||
|
--people-src: /_/icons/peoplelight.svg;
|
||||||
|
--people-selected-src: /_/icons/peoplelightselected.svg;
|
||||||
|
--settings-src: /_/icons/settingslight.svg;
|
||||||
|
--settings-selected-src: /_/icons/settingslightselected.svg;
|
||||||
|
--events-src: /_/icons/eventslight.svg;
|
||||||
|
--events-selected-src: /_/icons/eventslightselected.svg;
|
||||||
|
--jobs-src: /_/icons/jobslight.svg;
|
||||||
|
--jobs-selected-src: /_/icons/jobslightselected.svg;
|
||||||
|
|
||||||
|
--column-src: /_/icons/column2.svg;
|
||||||
|
--nodes-src: /_/icons/nodes.svg;
|
||||||
|
--forum-src: /_/icons/forum.svg;
|
||||||
|
--trash-src: /_/icons/trash.svg;
|
||||||
|
|
||||||
|
--pin-src: /_/icons/pinlight.svg;
|
||||||
|
--time-src: /_/icons/timelight.svg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
outline: none;
|
||||||
|
caret-color: var(--text); /* hide real caret */
|
||||||
|
}
|
||||||
|
|
||||||
|
input::placeholder {
|
||||||
|
font-family: Arial;
|
||||||
|
color: #5C504D;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--main);
|
||||||
|
padding-top: env(safe-area-inset-top);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
:root {
|
|
||||||
--main: #FFE9C8;
|
|
||||||
--accent: #60320c;
|
|
||||||
--text: #340000;
|
|
||||||
--yellow: #f1f3c3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding-top: env(safe-area-inset-top);
|
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
|
||||||
padding-left: env(safe-area-inset-left);
|
|
||||||
padding-right: env(safe-area-inset-right);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<svg width="118" height="108" viewBox="0 0 118 108" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M80.1955 59.9449H61.5784V107.52H80.1955V59.9449Z" fill="black"/>
|
|
||||||
<path d="M31.5063 59.9449H22.1965V107.52H31.5063V59.9449Z" fill="black"/>
|
|
||||||
<path d="M97.7112 0.0305315L97.7323 0H19.6963L19.7104 0.0305315C8.77192 0.356983 0 9.30504 0 20.3245C0 30.9295 8.12254 39.6251 18.4844 40.5563C22.3596 40.5458 31.0622 39.4924 31.4051 30.569C31.6188 24.9959 27.2599 20.2905 21.6879 20.0779L21.9063 14.3545C26.1361 14.5154 30.0476 16.3132 32.9223 19.418C35.7969 22.5216 37.2918 26.56 37.1298 30.7874C36.8068 39.1871 31.0998 44.8343 22.1987 46.0402V54.2168H95.2346V46.1436C91.7576 45.7373 88.6704 44.6558 86.1727 42.9272C82.1683 40.1618 79.9489 35.9801 79.7528 30.8332C79.5896 26.6058 81.0845 22.5686 83.9626 19.4661C86.835 16.3602 90.7477 14.5623 94.9751 14.4026L95.1947 20.1273C92.4962 20.2283 89.9997 21.3767 88.1642 23.3589C86.33 25.3411 85.3765 27.9175 85.4787 30.616C85.6043 33.9345 86.9348 36.4909 89.4313 38.2183C91.6249 39.7343 94.7203 40.5528 98.1985 40.5951C108.909 40.0232 117.429 31.1808 117.429 20.3245C117.429 9.30387 108.654 0.35346 97.7112 0.0305315Z" fill="black"/>
|
|
||||||
<path d="M95.2336 59.9449H85.9238V107.52H95.2336V59.9449Z" fill="black"/>
|
|
||||||
<path d="M55.8515 59.9449H37.2344V107.52H55.8515V59.9449Z" fill="black"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<svg width="28" height="32" viewBox="0 0 28 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M9.52366 0.0493342C4.88415 0.328928 1.12711 1.09781 0.253382 1.93659L0 2.18124V3.45688V4.73253L0.244645 4.9597C0.541713 5.23929 0.917417 5.43152 1.69504 5.69363C2.42023 5.94702 2.60372 5.96449 2.44645 5.77227C1.99211 5.22182 3.27649 4.584 5.7142 4.16461C8.0558 3.75395 9.35765 3.67532 13.5428 3.67532C17.728 3.67532 19.0299 3.75395 21.3715 4.16461C23.8354 4.584 25.0935 5.22182 24.6305 5.78974C24.5169 5.9208 24.5344 5.92954 24.7877 5.87712C25.3382 5.77227 26.4915 5.26551 26.7886 5.01212L27.0856 4.75001V3.45688V2.16376L26.7886 1.90164C25.9498 1.16771 22.8743 0.4862 18.7852 0.136707C17.3523 0.00564766 11.1401 -0.0467762 9.52366 0.0493342Z" fill="black"/>
|
|
||||||
<path d="M10.6246 5.30045C8.06453 5.44899 5.65304 5.82469 4.49971 6.26156C3.80073 6.52367 3.49492 6.83822 3.49492 7.27508V7.62458L4.0978 7.61584C4.63077 7.6071 4.73562 7.63331 4.93658 7.82553C5.06764 7.94786 5.20743 8.11386 5.25986 8.20997C5.31228 8.31482 5.33849 11.3292 5.32976 16.79L5.32102 25.2128H5.76662H6.20349V16.423C6.20349 6.60231 6.16854 7.15276 6.79762 6.89064C7.18207 6.73337 7.75873 6.80327 8.06453 7.03918C8.58877 7.45857 8.56256 6.82948 8.56256 18.1268V28.4456H9.17417H9.78578V17.8734C9.78578 11.4428 9.81199 7.24013 9.86442 7.14402C10.0741 6.75958 10.3974 6.56736 10.9216 6.53241C11.5158 6.48873 11.9526 6.68968 12.1361 7.0916C12.2148 7.26635 12.241 10.1671 12.2322 19.4549V31.591H13.5865H14.9408V19.4636C14.9408 7.59836 14.9408 7.33624 15.1155 7.06539C15.6136 6.24408 16.9853 6.34893 17.3436 7.24013C17.4571 7.52846 17.4746 8.89148 17.4746 18.0132V28.4543L18.0687 28.4281L18.6541 28.4019L18.6279 18.2229C18.6017 11.2069 18.6279 7.94786 18.6891 7.7469C18.9774 6.82948 20.2443 6.48873 20.7861 7.18771C20.9695 7.41488 20.9695 7.4673 20.9695 16.3095V25.2128H21.4064H21.8433V16.8424C21.8433 8.708 21.852 8.47209 22.018 8.20124C22.2714 7.77311 22.5597 7.63331 23.1189 7.64205H23.6169L23.5645 7.2314C23.5296 6.94307 23.4597 6.76832 23.2937 6.63726C22.1403 5.63247 16.0155 4.99465 10.6246 5.30045Z" fill="black"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,7 +0,0 @@
|
|||||||
<svg width="118" height="108" viewBox="0 0 118 108" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M80.1955 59.9449H61.5784V107.52H80.1955V59.9449Z" fill="#FEE8C8"/>
|
|
||||||
<path d="M31.5063 59.9449H22.1965V107.52H31.5063V59.9449Z" fill="#FEE8C8"/>
|
|
||||||
<path d="M97.7112 0.0305315L97.7323 0H19.6963L19.7104 0.0305315C8.77192 0.356983 0 9.30504 0 20.3245C0 30.9295 8.12254 39.6251 18.4844 40.5563C22.3596 40.5458 31.0622 39.4924 31.4051 30.569C31.6188 24.9959 27.2599 20.2905 21.6879 20.0779L21.9063 14.3545C26.1361 14.5154 30.0476 16.3132 32.9223 19.418C35.7969 22.5216 37.2918 26.56 37.1298 30.7874C36.8068 39.1871 31.0998 44.8342 22.1987 46.0402V54.2168H95.2346V46.1436C91.7576 45.7373 88.6704 44.6558 86.1727 42.9272C82.1683 40.1618 79.9489 35.9801 79.7528 30.8332C79.5896 26.6058 81.0845 22.5686 83.9626 19.4661C86.835 16.3602 90.7477 14.5623 94.9751 14.4026L95.1947 20.1273C92.4962 20.2283 89.9997 21.3767 88.1642 23.3589C86.33 25.3411 85.3765 27.9175 85.4787 30.616C85.6043 33.9345 86.9348 36.4909 89.4313 38.2183C91.6249 39.7343 94.7203 40.5528 98.1985 40.5951C108.909 40.0232 117.429 31.1808 117.429 20.3245C117.429 9.30387 108.654 0.35346 97.7112 0.0305315Z" fill="#FEE8C8"/>
|
|
||||||
<path d="M95.2336 59.9449H85.9238V107.52H95.2336V59.9449Z" fill="#FEE8C8"/>
|
|
||||||
<path d="M55.8515 59.9449H37.2344V107.52H55.8515V59.9449Z" fill="#FEE8C8"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 47 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100px" height="100px"><path d="M 17 21 A 1.0001 1.0001 0 0 0 16 22 L 16 32 A 1.0001 1.0001 0 0 0 17 33 L 83 33 A 1.0001 1.0001 0 0 0 84 32 L 84 22 A 1.0001 1.0001 0 0 0 83 21 L 17 21 z M 18 23 L 82 23 L 82 31 L 18 31 L 18 29 L 73.5 29 A 0.50005 0.50005 0 1 0 73.5 28 L 18 28 L 18 23 z M 76.5 28 A 0.50005 0.50005 0 1 0 76.5 29 L 78.5 29 A 0.50005 0.50005 0 1 0 78.5 28 L 76.5 28 z M 17 44 A 1.0001 1.0001 0 0 0 16 45 L 16 55 A 1.0001 1.0001 0 0 0 17 56 L 83 56 A 1.0001 1.0001 0 0 0 84 55 L 84 45 A 1.0001 1.0001 0 0 0 83 44 L 17 44 z M 18 46 L 82 46 L 82 54 L 18 54 L 18 46 z M 22.5 51 A 0.50005 0.50005 0 1 0 22.5 52 L 67.5 52 A 0.50005 0.50005 0 1 0 67.5 51 L 22.5 51 z M 70.5 51 A 0.50005 0.50005 0 1 0 70.5 52 L 73.5 52 A 0.50005 0.50005 0 1 0 73.5 51 L 70.5 51 z M 76.5 51 A 0.50005 0.50005 0 1 0 76.5 52 L 78.5 52 A 0.50005 0.50005 0 1 0 78.5 51 L 76.5 51 z M 17 67 A 1.0001 1.0001 0 0 0 16 68 L 16 78 A 1.0001 1.0001 0 0 0 17 79 L 83 79 A 1.0001 1.0001 0 0 0 84 78 L 84 68 A 1.0001 1.0001 0 0 0 83 67 L 17 67 z M 18 69 L 82 69 L 82 74 L 26.5 74 A 0.50005 0.50005 0 1 0 26.5 75 L 82 75 L 82 77 L 18 77 L 18 69 z M 21.5 74 A 0.50005 0.50005 0 1 0 21.5 75 L 23.5 75 A 0.50005 0.50005 0 1 0 23.5 74 L 21.5 74 z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
|
||||||
<path d="M0 0 C33 0 66 0 100 0 C100 23.76 100 47.52 100 72 C67 72 34 72 0 72 C0 48.24 0 24.48 0 0 Z M4 4 C3.46383745 8.70053019 3.46383745 8.70053019 5.30664062 10.5546875 C5.91701172 10.99039062 6.52738281 11.42609375 7.15625 11.875 C7.84114502 12.37870117 8.52604004 12.88240234 9.23168945 13.40136719 C9.98023193 13.92891602 10.72877441 14.45646484 11.5 15 C13.06813799 16.14868129 14.63450237 17.29978719 16.19921875 18.453125 C17.40070557 19.33194336 17.40070557 19.33194336 18.62646484 20.22851562 C22.28176453 22.95664302 25.79456149 25.84835522 29.3125 28.75 C31.2591282 30.33484221 33.20813973 31.91671841 35.15722656 33.49853516 C36.36876709 34.48568066 37.57657813 35.4774244 38.78027344 36.47412109 C40.40268905 37.81286849 42.04179632 39.1275644 43.6875 40.4375 C44.59886719 41.17871094 45.51023438 41.91992188 46.44921875 42.68359375 C48.88630843 44.26660079 48.88630843 44.26660079 51.37890625 43.5859375 C54.95082046 41.42468986 58.06328957 38.87595616 61.25 36.1875 C67.05660886 31.37582668 72.93368091 26.68843648 78.9375 22.125 C80.0061731 21.30745239 80.0061731 21.30745239 81.09643555 20.47338867 C84.06177854 18.20933035 87.03509444 15.97490703 90.0703125 13.8046875 C91.30394531 12.91136719 91.30394531 12.91136719 92.5625 12 C93.24441406 11.525625 93.92632812 11.05125 94.62890625 10.5625 C96.54964019 8.72009187 96.54964019 8.72009187 96 4 C65.64 4 35.28 4 4 4 Z M4 15 C4 32.49 4 49.98 4 68 C34.36 68 64.72 68 96 68 C96 50.51 96 33.02 96 15 C91.10723979 18.66957016 86.23777639 22.33985116 81.4375 26.125 C80.5556604 26.81843506 80.5556604 26.81843506 79.65600586 27.52587891 C76.42735841 30.06945531 73.21156659 32.62826175 70.0078125 35.203125 C69.01890015 35.99759033 69.01890015 35.99759033 68.01000977 36.80810547 C66.75119369 37.82090246 65.49376977 38.83543328 64.23803711 39.85205078 C63.07629198 40.7874235 61.90867537 41.71555794 60.73486328 42.63574219 C59.54616335 43.57050931 58.37318371 44.52551784 57.21435547 45.49707031 C54.26370419 47.84496996 52.75924576 48.97890984 48.90625 49.0859375 C45.41094599 47.77989648 43.28715117 46.10681719 40.5 43.625 C39.44697905 42.70771873 38.39222174 41.79242782 37.3359375 40.87890625 C36.7903418 40.40340332 36.24474609 39.92790039 35.68261719 39.43798828 C32.89861809 37.05874355 30.01440497 34.81161154 27.125 32.5625 C26.54911133 32.11293945 25.97322266 31.66337891 25.37988281 31.20019531 C24.19857561 30.27805578 23.01693136 29.35634787 21.83496094 28.43505859 C19.90812651 26.92814897 17.98846374 25.41247563 16.0703125 23.89453125 C15.43077637 23.38913818 14.79124023 22.88374512 14.13232422 22.36303711 C12.90121746 21.38980809 11.671035 20.41540842 10.44189453 19.43969727 C7.37045638 16.99238729 7.37045638 16.99238729 4 15 Z " fill="#000000" transform="translate(0,14)"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.8 KiB |
@@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 511.697 511.697" xml:space="preserve">
|
|
||||||
<g transform="translate(0 1)">
|
|
||||||
<g>
|
|
||||||
<path style="fill:#FFE100;" d="M505.189,119.472L505.189,119.472c-7.81-7.81-13.885-9.546-21.695-1.736l-45.125,45.993
|
|
||||||
c-6.075,6.075-14.753,6.075-20.827,0.868l-63.349-59.01c-4.339-4.339-10.414-6.942-16.488-6.942h-94.59l-79.837,75.498
|
|
||||||
c-7.81,7.81-9.546,21.695-1.736,30.373c8.678,9.546,22.563,8.678,31.241,0l59.01-62.481h43.39L147.656,306.916H62.612
|
|
||||||
c-13.885,0-26.902,10.414-27.769,24.298c-0.868,15.62,11.281,27.77,26.034,27.77H165.88c10.414,0,19.959-4.339,27.77-12.149
|
|
||||||
l57.275-61.614l61.614,65.085L296.05,456.177c-2.603,12.149,2.603,25.166,13.885,30.373c15.62,6.942,32.108-1.736,36.447-17.356
|
|
||||||
l25.166-135.376c0.868-6.075-0.868-11.281-5.207-15.62l-71.159-72.027l69.424-69.424l45.993,45.993
|
|
||||||
c7.81,7.81,21.695,7.81,29.505,0l19.959-19.959l45.125-52.068C513.867,142.035,513.867,128.15,505.189,119.472"/>
|
|
||||||
<path style="fill:#FFE100;" d="M462.667,118.605l-0.868-0.868c-7.81-7.81-1.736-7.81-10.414,0l-34.712,45.993
|
|
||||||
c-6.075,6.075-14.753,6.075-20.827,0.868l-73.763-59.01c-4.339-4.339-4.339-6.942-10.414-6.942h-68.556l-79.837,75.498
|
|
||||||
c-7.81,7.81-9.546,21.695-1.736,30.373c8.678,9.546,4.339,8.678,12.149,0l60.746-62.481h34.712L121.623,306.916h-59.01
|
|
||||||
c-13.885,0-26.902,10.414-27.769,24.298c-0.868,15.62,11.281,27.77,26.034,27.77h95.458l69.424-72.895l60.746,64.217
|
|
||||||
l-16.488,105.871c-2.603,12.149,2.603,25.166,13.885,30.373c15.62,6.942,16.488-1.736,19.959-17.356l20.827-144.922
|
|
||||||
l-55.539-78.102l63.349-69.424l40.786,45.993c7.81,7.81,18.224-3.471,26.034-11.281l8.678-8.678l54.671-54.671
|
|
||||||
C470.477,140.299,470.477,126.415,462.667,118.605"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path style="fill:#FFA800;" d="M323.819,324.272l-20.827,144.922c-2.603,11.281-3.471,19.092-10.414,19.959
|
|
||||||
c12.149,0.868,23.431-7.81,26.034-19.959l27.77-144.922l-77.234-77.234L323.819,324.272z"/>
|
|
||||||
<path style="fill:#FFA800;" d="M487.833,118.605l-0.868-0.868c-7.81-7.81-19.092-7.81-27.77-1.736
|
|
||||||
c0.868,0.868,0.868,0.868,1.736,1.736l0.868,0.868c7.81,7.81,7.81,20.827,0,29.505l-54.671,54.671l-8.678,8.678
|
|
||||||
c-4.339,4.339-8.678,9.546-13.885,12.149c7.81,6.942,20.827,6.942,28.637-0.868l19.959-19.959l54.671-54.671
|
|
||||||
C495.643,140.299,495.643,127.282,487.833,118.605"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path style="fill:#FFFFFF;" d="M163.277,207.12c-0.868-0.868-1.736-1.736-2.603-2.603c-7.81-8.678-6.942-21.695,1.736-30.373
|
|
||||||
l80.705-75.498H217.08l-79.837,75.498c-7.81,7.81-9.546,21.695-1.736,30.373S155.467,213.194,163.277,207.12"/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M34.843,331.215c0.868-13.885,13.017-24.298,26.902-24.298H35.711
|
|
||||||
c-13.885,0-26.902,10.414-27.769,24.298c0,15.62,12.149,27.77,26.902,27.77h26.034C46.124,358.984,33.975,346.835,34.843,331.215"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<path style="fill:#FFE100;" d="M425.351,63.933c0-24.298-19.092-43.39-43.39-43.39c-0.868,0-26.034,19.092-26.034,43.39
|
|
||||||
c0,0.868,1.736,43.39,26.034,43.39C406.26,107.323,425.351,88.232,425.351,63.933"/>
|
|
||||||
<g>
|
|
||||||
<path style="fill:#FFA800;" d="M399.318,20.543c-2.603,0-6.075,0-8.678,0.868c19.959,4.339,34.712,21.695,34.712,42.522
|
|
||||||
s-14.753,38.183-34.712,42.522c2.603,0.868,6.075,0.868,8.678,0.868c24.298,0,43.39-19.092,43.39-43.39
|
|
||||||
S423.616,20.543,399.318,20.543"/>
|
|
||||||
<path style="fill:#FFA800;" d="M356.795,71.743c0,0.868,0,0.868,0,1.736C356.795,72.611,356.795,71.743,356.795,71.743"/>
|
|
||||||
</g>
|
|
||||||
<path d="M295.182,497.832c-5.207,0-9.546-0.868-14.753-3.471c-14.753-6.942-23.431-23.431-19.092-40.786l15.62-100.664
|
|
||||||
l-52.068-54.671l-62.481,66.82c-1.736,1.736-3.471,2.603-6.075,2.603H34.843c-9.546,0-18.224-4.339-25.166-10.414
|
|
||||||
c-6.942-6.942-10.414-16.488-9.546-26.034c0.868-18.224,16.488-32.976,36.447-32.976h81.573l32.108-35.58
|
|
||||||
c3.471-3.471,8.678-3.471,12.149-0.868c3.471,3.471,3.471,8.678,0.868,12.149l-34.712,39.051c-2.603,1.736-4.339,2.603-6.942,2.603
|
|
||||||
H36.579c-10.414,0-19.092,6.942-19.092,16.488c0,5.207,1.736,9.546,4.339,13.017c3.471,3.471,7.81,5.207,13.017,5.207h118.02
|
|
||||||
l65.953-70.292c1.736-1.736,4.339-2.603,6.075-2.603c2.603,0,4.339,0.868,6.075,2.603l61.614,64.217
|
|
||||||
c1.736,1.736,2.603,4.339,2.603,6.942l-16.488,105.871c-1.736,9.546,1.736,18.224,9.546,21.695c5.207,2.603,10.414,1.736,14.753,0
|
|
||||||
c4.339-2.603,7.81-6.942,9.546-11.281l26.034-139.715l-74.63-74.631c-2.603-2.603-3.471-4.339-3.471-6.942
|
|
||||||
c0-2.603,0.868-4.339,2.603-6.075l69.424-69.424c3.471-3.471,8.678-3.471,12.149,0l45.993,45.993
|
|
||||||
c4.339,4.339,12.149,4.339,17.356,0l74.63-74.631c4.339-4.339,4.339-12.149,0-16.488l-0.868-0.868
|
|
||||||
c-5.207-5.207-13.017-5.207-17.356,0l-45.125,45.993c-8.678,8.678-23.431,9.546-32.976,0.868l-63.349-59.01
|
|
||||||
c-2.603-2.603-6.942-4.339-10.414-4.339h-91.986l-77.234,73.763c-5.207,5.207-5.207,13.017-0.868,18.224
|
|
||||||
c2.603,2.603,6.075,4.339,9.546,4.339l0,0c3.471,0,6.942-1.736,8.678-4.339l59.01-62.481c1.736-1.736,4.339-2.603,6.075-2.603
|
|
||||||
h43.39c3.471,0,6.942,1.736,7.81,5.207s0.868,6.942-1.736,9.546l-69.424,78.102c-3.471,3.471-8.678,4.339-12.149,0.868
|
|
||||||
c-3.471-3.471-3.471-8.678-0.868-12.149l56.407-63.349h-19.959l-56.407,59.878c-5.207,6.075-13.017,9.546-21.695,9.546l0,0
|
|
||||||
c-8.678,0-16.488-3.471-21.695-9.546c-10.414-11.281-9.546-30.373,1.736-42.522l79.837-76.366c1.736-3.471,3.471-4.339,6.075-4.339
|
|
||||||
h94.59c8.678,0,16.488,3.471,22.563,8.678l63.349,59.01c2.603,2.603,6.075,2.603,8.678,0l45.125-45.993
|
|
||||||
c11.281-11.281,30.373-11.281,42.522,0l0.868,0.868c11.281,11.281,11.281,30.373,0,41.654l-74.63,74.631
|
|
||||||
c-11.281,11.281-30.373,11.281-41.654,0l-39.919-39.919l-57.275,57.275l72.027,72.027c1.736,1.736,2.603,5.207,2.603,7.81
|
|
||||||
L329.026,470.93c-2.603,10.414-9.546,19.092-18.224,23.431C305.595,496.964,300.389,497.832,295.182,497.832z"/>
|
|
||||||
<path d="M187.575,241.832c0-5.207-3.471-8.678-8.678-8.678s-8.678,3.471-8.678,8.678s3.471,8.678,8.678,8.678
|
|
||||||
S187.575,247.038,187.575,241.832"/>
|
|
||||||
<path d="M399.318,116.001c-28.637,0-52.068-23.431-52.068-52.068s23.431-52.068,52.068-52.068
|
|
||||||
c28.637,0,52.068,23.431,52.068,52.068S427.955,116.001,399.318,116.001z M399.318,29.221c-19.092,0-34.712,15.62-34.712,34.712
|
|
||||||
s15.62,34.712,34.712,34.712c19.092,0,34.712-15.62,34.712-34.712S418.409,29.221,399.318,29.221z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -1,66 +0,0 @@
|
|||||||
import './ForumPanel.js'
|
|
||||||
|
|
||||||
css(`
|
|
||||||
forum- {
|
|
||||||
font-family: 'Bona';
|
|
||||||
}
|
|
||||||
|
|
||||||
forum- input::placeholder {
|
|
||||||
font-family: 'Bona Nova';
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
appearance: none; /* remove default style */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
border: 1px solid var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]:checked {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
class Forum extends Shadow {
|
|
||||||
|
|
||||||
selectedForum = "HY"
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
VStack(() => {
|
|
||||||
|
|
||||||
ForumPanel()
|
|
||||||
|
|
||||||
input("Message Hyperia", "98%")
|
|
||||||
.paddingVertical(1, em)
|
|
||||||
.paddingLeft(2, pct)
|
|
||||||
.color("var(--accent)")
|
|
||||||
.background("var(--darkbrown)")
|
|
||||||
.marginBottom(6, em)
|
|
||||||
.border("none")
|
|
||||||
.fontSize(1, em)
|
|
||||||
.onKeyDown(function (e) {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
window.Socket.send({app: "FORUM", operation: "SEND", msg: {forum: "HY", text: this.value }})
|
|
||||||
this.value = ""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.gap(0.5, em)
|
|
||||||
.width(100, pct)
|
|
||||||
.height(100, vh)
|
|
||||||
.horizontalAlign("center")
|
|
||||||
.verticalAlign("end")
|
|
||||||
})
|
|
||||||
.onAppear(() => document.body.style.backgroundColor = "var(--darkbrown)")
|
|
||||||
.width(100, pct)
|
|
||||||
.height(100, pct)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Forum)
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
import "../../components/LoadingCircle.js"
|
|
||||||
|
|
||||||
class ForumPanel extends Shadow {
|
|
||||||
forums = [
|
|
||||||
"HY"
|
|
||||||
]
|
|
||||||
messages = []
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
if(this.messages.length > 0) {
|
|
||||||
|
|
||||||
let previousDate = null
|
|
||||||
|
|
||||||
for(let i=0; i<this.messages.length; i++) {
|
|
||||||
let message = this.messages[i]
|
|
||||||
const dateParts = this.parseDate(message.time);
|
|
||||||
const { date, time } = dateParts;
|
|
||||||
|
|
||||||
if (previousDate !== date) {
|
|
||||||
previousDate = date;
|
|
||||||
|
|
||||||
p(date)
|
|
||||||
.textAlign("center")
|
|
||||||
.opacity(0.5)
|
|
||||||
.marginVertical(1, em)
|
|
||||||
.color("var(--divider)")
|
|
||||||
}
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
p(message.sentBy)
|
|
||||||
.fontWeight("bold")
|
|
||||||
.marginBottom(0.3, em)
|
|
||||||
|
|
||||||
p(util.formatTime(message.time))
|
|
||||||
.opacity(0.2)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
})
|
|
||||||
p(message.text)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LoadingCircle()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.gap(1, em)
|
|
||||||
.position("relative")
|
|
||||||
.overflow("scroll")
|
|
||||||
.height(100, pct)
|
|
||||||
.width(96, pct)
|
|
||||||
.paddingTop(5, em)
|
|
||||||
.paddingBottom(2, em)
|
|
||||||
.paddingLeft(4, pct)
|
|
||||||
.backgroundColor("var(--darkbrown)")
|
|
||||||
.onAppear(async () => {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
this.scrollTop = this.scrollHeight
|
|
||||||
});
|
|
||||||
let res = await Socket.send({app: "FORUM", operation: "GET", msg: {forum: "HY", number: 100}})
|
|
||||||
if(!res) console.error("failed to get messages")
|
|
||||||
if(res.msg.length > 0 && this.messages.length === 0) {
|
|
||||||
this.messages = res.msg
|
|
||||||
this.rerender()
|
|
||||||
}
|
|
||||||
window.addEventListener("new-post", (e) => {
|
|
||||||
this.messages = e.detail
|
|
||||||
if(e.detail.length !== this.messages || e.detail.last.time !== this.messages.last.time || e.detail.first.time !== this.messages.first.time) {
|
|
||||||
this.rerender()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
parseDate(str) {
|
|
||||||
// Format: MM.DD.YYYY-HH:MM:SSxxxxxx(am|pm)
|
|
||||||
const match = str.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})-(\d{1,2}):(\d{2}).*(am|pm)$/i);
|
|
||||||
if (!match) return null;
|
|
||||||
|
|
||||||
const [, mm, dd, yyyy, hh, min, ampm] = match;
|
|
||||||
const date = `${mm}/${dd}/${yyyy}`;
|
|
||||||
const time = `${hh}:${min}${ampm.toLowerCase()}`;
|
|
||||||
|
|
||||||
return { date, time };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(ForumPanel)
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import "./JobsSidebar.js"
|
|
||||||
import "./JobsGrid.js"
|
|
||||||
|
|
||||||
css(`
|
|
||||||
jobs- {
|
|
||||||
font-family: 'Bona';
|
|
||||||
}
|
|
||||||
|
|
||||||
jobs- input::placeholder {
|
|
||||||
font-family: 'Bona Nova';
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
appearance: none; /* remove default style */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
border: 1px solid var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]:checked {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
class Jobs extends Shadow {
|
|
||||||
jobs = [
|
|
||||||
{
|
|
||||||
title: "Austin Chapter Lead",
|
|
||||||
salary: "1% of Local Revenue",
|
|
||||||
company: "Hyperia",
|
|
||||||
city: "Austin",
|
|
||||||
state: "TX"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
JobsSidebar()
|
|
||||||
|
|
||||||
JobsGrid(this.jobs)
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.x(0).y(13, vh)
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input("Search jobs... (Coming Soon!)", "45vw")
|
|
||||||
.attr({
|
|
||||||
"type": "text",
|
|
||||||
"disabled": "true"
|
|
||||||
})
|
|
||||||
.fontSize(1.1, em)
|
|
||||||
.paddingLeft(1.3, em)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--divider)")
|
|
||||||
.outline("none")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.opacity(0.5)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("grey")
|
|
||||||
.cursor("not-allowed")
|
|
||||||
|
|
||||||
button("+ Add Job")
|
|
||||||
.width(7, em)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.3px solid var(--accent2)")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.fontFamily("Bona Nova")
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.background = "var(--green)"
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.style.background = "transparent"
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onClick((clicking) => {
|
|
||||||
console.log(this, "clicked")
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.x(55, vw).y(4, vh)
|
|
||||||
.position("absolute")
|
|
||||||
.transform("translateX(-50%)")
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.height(100, "%")
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
// Optional additional logic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Jobs)
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
class JobsGrid extends Shadow {
|
|
||||||
jobs;
|
|
||||||
|
|
||||||
constructor(jobs) {
|
|
||||||
super()
|
|
||||||
this.jobs = jobs
|
|
||||||
}
|
|
||||||
|
|
||||||
boldUntilFirstSpace(text) {
|
|
||||||
const index = text.indexOf(' ');
|
|
||||||
if (index === -1) {
|
|
||||||
// No spaces — bold the whole thing
|
|
||||||
return `<b>${text}</b>`;
|
|
||||||
}
|
|
||||||
return `<b>${text.slice(0, index)}</b>${text.slice(index)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
h3("Results")
|
|
||||||
.marginTop(0.1, em)
|
|
||||||
.marginBottom(1, em)
|
|
||||||
.marginLeft(0.4, em)
|
|
||||||
.color("var(--accent2)")
|
|
||||||
|
|
||||||
if (this.jobs.length > 0) {
|
|
||||||
ZStack(() => {
|
|
||||||
for (let i = 0; i < this.jobs.length; i++) {
|
|
||||||
VStack(() => {
|
|
||||||
p(this.jobs[i].title)
|
|
||||||
.fontSize(1.2, em)
|
|
||||||
.fontWeight("bold")
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
p(this.jobs[i].company)
|
|
||||||
p(this.jobs[i].city + ", " + this.jobs[i].state)
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
p(this.boldUntilFirstSpace(this.jobs[i].salary))
|
|
||||||
})
|
|
||||||
.padding(1, em)
|
|
||||||
.borderRadius(5, "px")
|
|
||||||
.background("var(--darkbrown)")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.display("grid")
|
|
||||||
.gridTemplateColumns("repeat(auto-fill, minmax(250px, 1fr))")
|
|
||||||
.gap(1, em)
|
|
||||||
} else {
|
|
||||||
p("No Jobs!")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.height(100, vh)
|
|
||||||
.paddingLeft(2, em)
|
|
||||||
.paddingRight(2, em)
|
|
||||||
.paddingTop(2, em)
|
|
||||||
.gap(0, em)
|
|
||||||
.width(100, "%")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(JobsGrid)
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
class JobsSidebar extends Shadow {
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
h3("Location")
|
|
||||||
.color("var(--accent2)")
|
|
||||||
.marginBottom(0, em)
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input("Location", "100%")
|
|
||||||
.paddingLeft(3, em)
|
|
||||||
.paddingVertical(0.75, em)
|
|
||||||
.backgroundImage("/_/icons/locationPin.svg")
|
|
||||||
.backgroundRepeat("no-repeat")
|
|
||||||
.backgroundSize("18px 18px")
|
|
||||||
.backgroundPosition("10px center")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.paddingTop(1, em)
|
|
||||||
.paddingLeft(3, em)
|
|
||||||
.paddingRight(3, em)
|
|
||||||
.gap(1, em)
|
|
||||||
.minWidth(10, vw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(JobsSidebar)
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
import "./MarketSidebar.js"
|
|
||||||
import "./MarketGrid.js"
|
|
||||||
|
|
||||||
css(`
|
|
||||||
market- {
|
|
||||||
font-family: 'Bona';
|
|
||||||
}
|
|
||||||
|
|
||||||
market- input::placeholder {
|
|
||||||
font-family: 'Bona Nova';
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
appearance: none; /* remove default style */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
border: 1px solid var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]:checked {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
class Market extends Shadow {
|
|
||||||
|
|
||||||
listings = [
|
|
||||||
{
|
|
||||||
title: "Shield Lapel Pin",
|
|
||||||
stars: "5",
|
|
||||||
reviews: 1,
|
|
||||||
price: "$12",
|
|
||||||
company: "Hyperia",
|
|
||||||
type: "new",
|
|
||||||
image: "/db/images/1",
|
|
||||||
madeIn: "America"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
MarketSidebar()
|
|
||||||
|
|
||||||
MarketGrid(this.listings)
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.x(0).y(13, vh)
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input("Search for products... (Coming Soon!)", "45vw")
|
|
||||||
.attr({
|
|
||||||
"type": "text",
|
|
||||||
"disabled": "true"
|
|
||||||
})
|
|
||||||
.fontSize(1.1, em)
|
|
||||||
.paddingLeft(1.3, em)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--divider)")
|
|
||||||
.outline("none")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.opacity(0.5)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("grey")
|
|
||||||
.cursor("not-allowed")
|
|
||||||
|
|
||||||
button("+ Add Item")
|
|
||||||
.width(7, em)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--accent2)")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.fontFamily("Bona Nova")
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.background = "var(--green)"
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.style.background = "transparent"
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onClick((clicking) => {
|
|
||||||
console.log(this, "clicked")
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.x(55, vw).y(4, vh)
|
|
||||||
.position("absolute")
|
|
||||||
.transform("translateX(-50%)")
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.height(100, "%")
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
// Optional additional logic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Market)
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
class MarketGrid extends Shadow {
|
|
||||||
listings;
|
|
||||||
|
|
||||||
constructor(listings) {
|
|
||||||
super()
|
|
||||||
this.listings = listings
|
|
||||||
}
|
|
||||||
|
|
||||||
boldUntilFirstSpace(text) {
|
|
||||||
if(!text) return
|
|
||||||
const index = text.indexOf(' ');
|
|
||||||
if (index === -1) {
|
|
||||||
// No spaces — bold the whole thing
|
|
||||||
return `<b>${text}</b>`;
|
|
||||||
}
|
|
||||||
return `<b>${text.slice(0, index)}</b>${text.slice(index)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
h3("Results")
|
|
||||||
.marginTop(0.1, em)
|
|
||||||
.marginBottom(1, em)
|
|
||||||
.marginLeft(0.4, em)
|
|
||||||
.color("var(--accent)")
|
|
||||||
.opacity(0.7)
|
|
||||||
|
|
||||||
if (this.listings.length > 0) {
|
|
||||||
ZStack(() => {
|
|
||||||
// BuyModal()
|
|
||||||
|
|
||||||
let params = new URLSearchParams(window.location.search);
|
|
||||||
|
|
||||||
const hyperiaMade = params.get("hyperia-made") === "true";
|
|
||||||
const americaMade = params.get("america-made") === "true";
|
|
||||||
const newItem = params.get("new") === "true";
|
|
||||||
const usedItem = params.get("used") === "true";
|
|
||||||
|
|
||||||
|
|
||||||
let filtered = this.listings;
|
|
||||||
if (hyperiaMade) {
|
|
||||||
filtered = filtered.filter(item => item.madeIn === "Hyperia");
|
|
||||||
}
|
|
||||||
if (americaMade) {
|
|
||||||
filtered = filtered.filter(item => item.madeIn === "America");
|
|
||||||
}
|
|
||||||
if (newItem) {
|
|
||||||
filtered = filtered.filter(item => item.type === "new");
|
|
||||||
}
|
|
||||||
if (usedItem) {
|
|
||||||
filtered = filtered.filter(item => item.type === "used");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < filtered.length; i++) {
|
|
||||||
const rating = filtered[i].stars
|
|
||||||
const percent = (rating / 5)
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
img(filtered[i].image)
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
|
|
||||||
p(filtered[i].company)
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
|
|
||||||
p(filtered[i].title)
|
|
||||||
.fontSize(1.2, em)
|
|
||||||
.fontWeight("bold")
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
p(filtered[i].stars)
|
|
||||||
.marginRight(0.2, em)
|
|
||||||
|
|
||||||
ZStack(() => {
|
|
||||||
div("★★★★★") // Empty stars (background)
|
|
||||||
.color("#ccc")
|
|
||||||
|
|
||||||
div("★★★★★") // Filled stars (foreground, clipped by width)
|
|
||||||
.color("#ffa500")
|
|
||||||
.position("absolute")
|
|
||||||
.top(0)
|
|
||||||
.left(0)
|
|
||||||
.whiteSpace("nowrap")
|
|
||||||
.overflow("hidden")
|
|
||||||
.width(percent * 5, em)
|
|
||||||
})
|
|
||||||
.display("inline-block")
|
|
||||||
.position("relative")
|
|
||||||
.fontSize(1.2, em)
|
|
||||||
.lineHeight(1)
|
|
||||||
|
|
||||||
p(filtered[i].reviews)
|
|
||||||
.marginLeft(0.2, em)
|
|
||||||
})
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
|
|
||||||
p(filtered[i].price)
|
|
||||||
.fontSize(1.75, em)
|
|
||||||
.marginBottom(0.5, em)
|
|
||||||
|
|
||||||
button("Coming Soon!")
|
|
||||||
.onClick((finished) => {
|
|
||||||
if(finished) {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.backgroundColor = "var(--green)"
|
|
||||||
} else {
|
|
||||||
this.style.backgroundColor = ""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.padding(1, em)
|
|
||||||
.border("1px solid var(--accent2)")
|
|
||||||
.borderRadius(5, "px")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.display("grid")
|
|
||||||
.gridTemplateColumns("repeat(auto-fill, minmax(250px, 1fr))")
|
|
||||||
.gap(1, em)
|
|
||||||
} else {
|
|
||||||
p("No Listings!")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onQueryChanged(() => {
|
|
||||||
console.log("query did change yup")
|
|
||||||
this.rerender()
|
|
||||||
})
|
|
||||||
.height(100, vh)
|
|
||||||
.paddingLeft(2, em)
|
|
||||||
.paddingRight(2, em)
|
|
||||||
.gap(0, em)
|
|
||||||
.width(100, "%")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(MarketGrid)
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
class MarketSidebar extends Shadow {
|
|
||||||
|
|
||||||
handleChecked(e) {
|
|
||||||
let checked = e.target.checked
|
|
||||||
let label = $(`label[for="${e.target.id}"]`).innerText
|
|
||||||
if(checked) {
|
|
||||||
window.setQuery(label.toLowerCase(), true)
|
|
||||||
} else {
|
|
||||||
window.setQuery(label.toLowerCase(), null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
|
|
||||||
p("Make")
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input()
|
|
||||||
.attr({
|
|
||||||
"type": "checkbox",
|
|
||||||
"id": "hyperia-check"
|
|
||||||
})
|
|
||||||
.onChange(this.handleChecked)
|
|
||||||
label("Hyperia-Made")
|
|
||||||
.attr({
|
|
||||||
"for": "hyperia-check"
|
|
||||||
})
|
|
||||||
.marginLeft(0.5, em)
|
|
||||||
})
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input()
|
|
||||||
.attr({
|
|
||||||
"type": "checkbox",
|
|
||||||
"id": "america-check"
|
|
||||||
})
|
|
||||||
.onChange(this.handleChecked)
|
|
||||||
label("America-Made")
|
|
||||||
.attr({
|
|
||||||
"for": "america-check"
|
|
||||||
})
|
|
||||||
.marginLeft(0.5, em)
|
|
||||||
})
|
|
||||||
|
|
||||||
p("Condition")
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input()
|
|
||||||
.attr({
|
|
||||||
"type": "checkbox",
|
|
||||||
"id": "new-check"
|
|
||||||
})
|
|
||||||
.onChange(this.handleChecked)
|
|
||||||
label("New")
|
|
||||||
.attr({
|
|
||||||
"for": "new-check"
|
|
||||||
})
|
|
||||||
.marginLeft(0.5, em)
|
|
||||||
})
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input()
|
|
||||||
.attr({
|
|
||||||
"type": "checkbox",
|
|
||||||
"id": "used-check"
|
|
||||||
})
|
|
||||||
.onChange(this.handleChecked)
|
|
||||||
label("Used")
|
|
||||||
.attr({
|
|
||||||
"for": "used-check"
|
|
||||||
})
|
|
||||||
.marginLeft(0.5, em)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.paddingTop(12, vh)
|
|
||||||
.paddingLeft(3, em)
|
|
||||||
.paddingRight(3, em)
|
|
||||||
.gap(1, em)
|
|
||||||
.minWidth(10, vw)
|
|
||||||
.userSelect('none')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(MarketSidebar)
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
import "./MessagesSidebar.js"
|
|
||||||
import "./MessagesPanel.js"
|
|
||||||
|
|
||||||
css(`
|
|
||||||
messages- {
|
|
||||||
font-family: 'Bona';
|
|
||||||
}
|
|
||||||
|
|
||||||
messages- input::placeholder {
|
|
||||||
font-family: 'Bona Nova';
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
appearance: none; /* remove default style */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
border: 1px solid var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]:checked {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
class Messages extends Shadow {
|
|
||||||
conversations = []
|
|
||||||
selectedConvoID = null
|
|
||||||
onConversationSelect(i) {
|
|
||||||
console.log("convo selected: ", i)
|
|
||||||
this.selectedConvoID = i
|
|
||||||
this.$("messagessidebar-").rerender()
|
|
||||||
this.$("messagespanel-").rerender()
|
|
||||||
}
|
|
||||||
|
|
||||||
getConvoFromID(id) {
|
|
||||||
for(let i=0; i<this.conversations.length; i++) {
|
|
||||||
if(this.conversations[i].id === id) {
|
|
||||||
return this.conversations[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
MessagesSidebar(this.conversations, this.selectedConvoID, this.onConversationSelect)
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
if(this.getConvoFromID(this.selectedConvoID)) {
|
|
||||||
MessagesPanel(this.getConvoFromID(this.selectedConvoID).messages)
|
|
||||||
} else {
|
|
||||||
MessagesPanel()
|
|
||||||
}
|
|
||||||
|
|
||||||
input("Send Message", "93%")
|
|
||||||
.paddingVertical(1, em)
|
|
||||||
.paddingHorizontal(2, em)
|
|
||||||
.color("var(--accent)")
|
|
||||||
.background("var(--darkbrown)")
|
|
||||||
.marginBottom(6, em)
|
|
||||||
.border("none")
|
|
||||||
.fontSize(1, em)
|
|
||||||
.onKeyDown((e) => {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
window.Socket.send({app: "MESSAGES", operation: "SEND", msg: { conversation: `CONVERSATION-${this.selectedConvoID}`, text: e.target.value }})
|
|
||||||
e.target.value = ""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.gap(1, em)
|
|
||||||
.width(100, pct)
|
|
||||||
.horizontalAlign("center")
|
|
||||||
.verticalAlign("end")
|
|
||||||
})
|
|
||||||
.onAppear(async () => {
|
|
||||||
let res = await Socket.send({app: "MESSAGES", operation: "GET"})
|
|
||||||
if(!res) console.error("failed to get messages")
|
|
||||||
|
|
||||||
if(res.msg.length > 0 && this.conversations.length === 0) {
|
|
||||||
this.conversations = res.msg
|
|
||||||
this.selectedConvoID = this.conversations[0].id
|
|
||||||
this.rerender()
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("new-message", (e) => {
|
|
||||||
let convoID = e.detail.conversationID
|
|
||||||
let messages = e.detail.messages
|
|
||||||
let convo = this.getConvoFromID(convoID)
|
|
||||||
convo.messages = messages
|
|
||||||
this.rerender()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.height(87, vh)
|
|
||||||
.x(0).y(13, vh)
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
p("Add Message")
|
|
||||||
|
|
||||||
input("enter email...")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.onKeyDown(function (e) {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
window.Socket.send({app: "MESSAGES", operation: "ADDCONVERSATION", msg: {email: this.value }})
|
|
||||||
this.value = ""
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
p("x")
|
|
||||||
.onClick(function (done) {
|
|
||||||
if(done) {
|
|
||||||
this.parentElement.style.display = "none"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.xRight(2, em).y(2, em)
|
|
||||||
.fontSize(1.4, em)
|
|
||||||
.cursor("pointer")
|
|
||||||
|
|
||||||
})
|
|
||||||
.gap(1, em)
|
|
||||||
.alignVertical("center")
|
|
||||||
.alignHorizontal("center")
|
|
||||||
.backgroundColor("black")
|
|
||||||
.border("1px solid var(--accent)")
|
|
||||||
.position("fixed")
|
|
||||||
.x(50, vw).y(50, vh)
|
|
||||||
.center()
|
|
||||||
.width(60, vw)
|
|
||||||
.height(60, vh)
|
|
||||||
.display("none")
|
|
||||||
.attr({id: "addPanel"})
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input("Search messages... (Coming Soon!)", "45vw")
|
|
||||||
.attr({
|
|
||||||
"type": "text",
|
|
||||||
"disabled": "true"
|
|
||||||
})
|
|
||||||
.fontSize(1.1, em)
|
|
||||||
.paddingLeft(1.3, em)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--divider)")
|
|
||||||
.outline("none")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.opacity(0.5)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("grey")
|
|
||||||
.cursor("not-allowed")
|
|
||||||
|
|
||||||
button("+ New Message")
|
|
||||||
.width(13, em)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--divider)")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.fontFamily("Bona Nova")
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.background = "var(--green)"
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.style.background = "transparent"
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onClick((done) => {
|
|
||||||
console.log("click")
|
|
||||||
if(done) {
|
|
||||||
this.$("#addPanel").style.display = "flex"
|
|
||||||
}
|
|
||||||
console.log(this, "clicked")
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.x(55, vw).y(4, vh)
|
|
||||||
.position("absolute")
|
|
||||||
.transform("translateX(-50%)")
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.height(100, "%")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Messages)
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import "../../components/LoadingCircle.js"
|
|
||||||
|
|
||||||
class MessagesPanel extends Shadow {
|
|
||||||
messages
|
|
||||||
|
|
||||||
constructor(messages) {
|
|
||||||
super()
|
|
||||||
this.messages = messages
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
if(this.messages) {
|
|
||||||
for(let i=0; i<this.messages.length; i++) {
|
|
||||||
let message = this.messages[i]
|
|
||||||
let fromMe = window.profile.email === message.from.email
|
|
||||||
VStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
p(message.from.firstName + " " + message.from.lastName)
|
|
||||||
.fontWeight("bold")
|
|
||||||
.marginBottom(0.3, em)
|
|
||||||
|
|
||||||
p(util.formatTime(message.time))
|
|
||||||
.opacity(0.2)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
})
|
|
||||||
p(message.text)
|
|
||||||
})
|
|
||||||
.paddingVertical(0.5, em)
|
|
||||||
.marginLeft(fromMe ? 70 : 0, pct)
|
|
||||||
.paddingRight(fromMe ? 10 : 0, pct)
|
|
||||||
.marginRight(fromMe ? 0 : 70, pct)
|
|
||||||
.paddingLeft(fromMe ? 5 : 10, pct)
|
|
||||||
.background(fromMe ? "var(--brown)" : "var(--green)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LoadingCircle()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onAppear(async () => {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
this.scrollTop = this.scrollHeight
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.gap(1, em)
|
|
||||||
.position("relative")
|
|
||||||
.overflow("scroll")
|
|
||||||
.height(95, pct)
|
|
||||||
.width(100, pct)
|
|
||||||
.paddingTop(2, em)
|
|
||||||
.paddingBottom(2, em)
|
|
||||||
.backgroundColor("var(--darkbrown)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(MessagesPanel)
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
class MessagesSidebar extends Shadow {
|
|
||||||
conversations = []
|
|
||||||
selectedConvoID
|
|
||||||
onSelect
|
|
||||||
|
|
||||||
constructor(conversations, selectedConvoID, onSelect) {
|
|
||||||
super()
|
|
||||||
this.conversations = conversations
|
|
||||||
this.selectedConvoID = selectedConvoID
|
|
||||||
this.onSelect = onSelect
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
this.conversations.forEach((convo, i) => {
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
|
|
||||||
p(this.makeConvoTitle(convo.between))
|
|
||||||
.textAlign("left")
|
|
||||||
.marginLeft(0.5, inches)
|
|
||||||
.paddingTop(0.2, inches)
|
|
||||||
.width(100, pct)
|
|
||||||
.marginTop(0)
|
|
||||||
.fontSize(1, em)
|
|
||||||
.fontWeight("bold")
|
|
||||||
|
|
||||||
p(util.formatTime(convo.messages.last.time))
|
|
||||||
.paddingTop(0.2, inches)
|
|
||||||
.fontSize(0.8, em)
|
|
||||||
.marginRight(0.1, inches)
|
|
||||||
.color("var(--divider")
|
|
||||||
})
|
|
||||||
.justifyContent("space-between")
|
|
||||||
.marginBottom(0)
|
|
||||||
|
|
||||||
p(convo.messages.last.text)
|
|
||||||
.fontSize(0.8, em)
|
|
||||||
.textAlign("left")
|
|
||||||
.marginLeft(0.5, inches)
|
|
||||||
.marginBottom(2, em)
|
|
||||||
.color("var(--divider)")
|
|
||||||
})
|
|
||||||
.background(convo.id === this.selectedConvoID ? "var(--darkbrown)" : "")
|
|
||||||
.onClick(() => {
|
|
||||||
this.onSelect(i)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.minWidth(15, vw)
|
|
||||||
.height(100, vh)
|
|
||||||
.gap(0, em)
|
|
||||||
}
|
|
||||||
|
|
||||||
makeConvoTitle(members) {
|
|
||||||
let membersString = ""
|
|
||||||
for(let i=0; i<members.length; i++) {
|
|
||||||
let member = members[i]
|
|
||||||
if(member.email === window.profile.email) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(members.length > 2) {
|
|
||||||
membersString += member.firstName
|
|
||||||
} else {
|
|
||||||
membersString += member.firstName + " " + member.lastName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return membersString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(MessagesSidebar)
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
css(`
|
|
||||||
tasks- {
|
|
||||||
font-family: 'Bona';
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks- input::placeholder {
|
|
||||||
font-family: 'Bona Nova';
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
appearance: none; /* remove default style */
|
|
||||||
-webkit-appearance: none;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
border: 1px solid var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]:checked {
|
|
||||||
background-color: var(--red);
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
class Tasks extends Shadow {
|
|
||||||
projects = [
|
|
||||||
{
|
|
||||||
"title": "Blockcatcher",
|
|
||||||
"tasks": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
"title": "backlog",
|
|
||||||
"tasks": {}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
HStack(() => {
|
|
||||||
VStack(() => {
|
|
||||||
h3("Projects")
|
|
||||||
.marginTop(0)
|
|
||||||
.marginBottom(1, em)
|
|
||||||
.marginLeft(0.4, em)
|
|
||||||
|
|
||||||
if (this.projects.length >= 1) {
|
|
||||||
for(let i = 0; i < this.projects.length; i++) {
|
|
||||||
p(this.projects[i].title)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p("No Projects!")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.height(100, vh)
|
|
||||||
.paddingLeft(2, em)
|
|
||||||
.paddingRight(2, em)
|
|
||||||
.paddingTop(2, em)
|
|
||||||
.gap(0, em)
|
|
||||||
.borderRight("0.5px solid var(--accent2)")
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
if (this.columns.length >= 1) {
|
|
||||||
for(let i = 0; i < this.columns.length; i++) {
|
|
||||||
p(this.columns[i].name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p("No Conversations!")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.height(100, vh)
|
|
||||||
.paddingLeft(2, em)
|
|
||||||
.paddingRight(2, em)
|
|
||||||
.paddingTop(2, em)
|
|
||||||
.gap(0, em)
|
|
||||||
.borderRight("0.5px solid var(--accent2)")
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.x(0).y(13, vh)
|
|
||||||
.borderTop("0.5px solid var(--accent2)")
|
|
||||||
|
|
||||||
p("0 Items")
|
|
||||||
.position("absolute")
|
|
||||||
.x(50, vw).y(50, vh)
|
|
||||||
.transform("translate(-50%, -50%)")
|
|
||||||
|
|
||||||
HStack(() => {
|
|
||||||
input("Search tasks...", "45vw")
|
|
||||||
.attr({
|
|
||||||
"type": "text"
|
|
||||||
})
|
|
||||||
.fontSize(1.1, em)
|
|
||||||
.paddingLeft(1.3, em)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--accent2)")
|
|
||||||
.outline("none")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.borderRadius(10, px)
|
|
||||||
|
|
||||||
button("Search")
|
|
||||||
.marginLeft(2, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--accent2)")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.fontFamily("Bona Nova")
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.background = "var(--green)"
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.style.background = "transparent"
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
button("+ New Task")
|
|
||||||
.width(9, em)
|
|
||||||
.marginLeft(1, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.background("transparent")
|
|
||||||
.border("0.5px solid var(--accent2)")
|
|
||||||
.color("var(--accent)")
|
|
||||||
.fontFamily("Bona Nova")
|
|
||||||
.onHover(function (hovering) {
|
|
||||||
if(hovering) {
|
|
||||||
this.style.background = "var(--green)"
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.style.background = "transparent"
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onClick((clicking) => {
|
|
||||||
console.log(this, "clicked")
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.x(55, vw).y(4, vh)
|
|
||||||
.position("absolute")
|
|
||||||
.transform("translateX(-50%)")
|
|
||||||
})
|
|
||||||
.width(100, "%")
|
|
||||||
.height(100, "%")
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
// Optional additional logic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Tasks)
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
class AppMenu extends Shadow {
|
|
||||||
selected = ""
|
|
||||||
|
|
||||||
onNewSelection() {
|
|
||||||
this.$$("img").forEach((image) => {
|
|
||||||
image.style.background = ""
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
console.log("rendering")
|
|
||||||
HStack(() => {
|
|
||||||
img("/_/icons/Column.svg", "1.5em", "1.5em")
|
|
||||||
.attr({app: "forum"})
|
|
||||||
.padding(0.5, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.onClick((finished, e) => {
|
|
||||||
if(finished) {
|
|
||||||
this.onNewSelection()
|
|
||||||
}
|
|
||||||
e.target.style.background = "var(--accent)"
|
|
||||||
console.log(e.target, e.target.style.background)
|
|
||||||
if(finished) {
|
|
||||||
window.navigateTo("/")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
img("/_/icons/letter.svg", "1.5em", "1.5em")
|
|
||||||
.attr({app: "messages"})
|
|
||||||
.padding(0.5, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.onClick((finished, e) => {
|
|
||||||
if(finished) {
|
|
||||||
this.onNewSelection()
|
|
||||||
}
|
|
||||||
e.target.style.background = "rgb(112 150 114)"
|
|
||||||
if(finished) {
|
|
||||||
window.navigateTo("/messages")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
img("/_/icons/jobs.svg", "1.5em", "1.5em")
|
|
||||||
.attr({app: "jobs"})
|
|
||||||
.padding(0.5, em)
|
|
||||||
.borderRadius(10, px)
|
|
||||||
.onClick((finished, e) => {
|
|
||||||
if(finished) {
|
|
||||||
this.onNewSelection()
|
|
||||||
}
|
|
||||||
e.target.style.background = "#9392bb"
|
|
||||||
if(finished) {
|
|
||||||
window.navigateTo("/jobs")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.borderTop("1px solid black")
|
|
||||||
.height("auto")
|
|
||||||
.position('fixed')
|
|
||||||
.background("var(--main)")
|
|
||||||
.zIndex(1)
|
|
||||||
.x(0).yBottom(0)
|
|
||||||
.justifyContent("space-between")
|
|
||||||
.paddingHorizontal(4, em)
|
|
||||||
.paddingVertical(1, em)
|
|
||||||
.width(100, vw)
|
|
||||||
.boxSizing("border-box")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(AppMenu)
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
class LoadingCircle extends Shadow {
|
|
||||||
render() {
|
|
||||||
div()
|
|
||||||
.borderRadius(100, pct)
|
|
||||||
.width(2, em).height(2, em)
|
|
||||||
.x(45, pct).y(50, pct)
|
|
||||||
.center()
|
|
||||||
.backgroundColor("var(--accent")
|
|
||||||
.transition("transform 1.75s ease-in-out")
|
|
||||||
.onAppear(function () {
|
|
||||||
let growing = true;
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
if (growing) {
|
|
||||||
this.style.transform = "scale(1.5)";
|
|
||||||
} else {
|
|
||||||
this.style.transform = "scale(0.7)";
|
|
||||||
}
|
|
||||||
growing = !growing;
|
|
||||||
}, 750);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(LoadingCircle)
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
class Sidebar extends Shadow {
|
|
||||||
|
|
||||||
SidebarItem(text) {
|
|
||||||
return p(text)
|
|
||||||
.fontSize(1.5, em)
|
|
||||||
.fontWeight("bold")
|
|
||||||
.fontFamily("Sedan SC")
|
|
||||||
.marginLeft(2, em)
|
|
||||||
.fontStyle("italic")
|
|
||||||
.onClick(function () {
|
|
||||||
if(this.innerText === "Home") {
|
|
||||||
window.navigateTo("/")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
window.navigateTo(this.innerText.toLowerCase().replace(/\s+/g, ""))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
VStack(() => {
|
|
||||||
this.SidebarItem("Home")
|
|
||||||
this.SidebarItem("Map")
|
|
||||||
this.SidebarItem("Logout")
|
|
||||||
})
|
|
||||||
.gap(2, em)
|
|
||||||
.paddingTop(30, vh)
|
|
||||||
.height(100, vh)
|
|
||||||
.width(70, vw)
|
|
||||||
.borderLeft("1px solid black")
|
|
||||||
.position("fixed")
|
|
||||||
.background("var(--main)")
|
|
||||||
.xRight(-70, vw)
|
|
||||||
.transition("right .3s")
|
|
||||||
.zIndex(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
if(this.style.right === "-70vw") {
|
|
||||||
this.style.right = "0vw"
|
|
||||||
} else {
|
|
||||||
this.style.right = "-70vw"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Sidebar)
|
|
||||||
116
src/index.html
@@ -5,25 +5,111 @@
|
|||||||
<title>Forum</title>
|
<title>Forum</title>
|
||||||
<meta
|
<meta
|
||||||
name="viewport"
|
name="viewport"
|
||||||
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
content="viewport-fit=auto, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
/>
|
/>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="msapplication-tap-highlight" content="no" />
|
<meta name="msapplication-tap-highlight" content="no" />
|
||||||
|
|
||||||
<script
|
|
||||||
type="module"
|
|
||||||
src="https://unpkg.com/@ionic/pwa-elements@latest/dist/ionicpwaelements/ionicpwaelements.esm.js"
|
|
||||||
></script>
|
|
||||||
<script
|
|
||||||
nomodule
|
|
||||||
src="https://unpkg.com/@ionic/pwa-elements@latest/dist/ionicpwaelements/ionicpwaelements.js"
|
|
||||||
></script>
|
|
||||||
|
|
||||||
<link rel="icon" type="image/x-icon" href="./_/icons/columnwhite.svg" />
|
|
||||||
<link rel="manifest" href="./manifest.json" />
|
<link rel="manifest" href="./manifest.json" />
|
||||||
<link rel="stylesheet" href="./_/code/styles.css" />
|
<link rel="stylesheet" href="./_/code/shared.css" />
|
||||||
<script src="./_/code/quill.js"></script>
|
<script type="module">
|
||||||
<script type="module" src="./index.js"></script>
|
await import('./util.js')
|
||||||
|
|
||||||
|
function appendScript(src, isModule = false) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const s = document.createElement('script')
|
||||||
|
s.src = src
|
||||||
|
s.crossOrigin = "anonymous"
|
||||||
|
if (isModule) s.type = 'module'
|
||||||
|
s.onload = resolve
|
||||||
|
s.onerror = reject
|
||||||
|
document.head.appendChild(s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await appendScript(window.util.HOST + '/_/code/quill.js')
|
||||||
|
await appendScript(window.util.HOST + '/83947261/index.js', true)
|
||||||
|
} catch (e) {
|
||||||
|
document.body.innerHTML = `
|
||||||
|
<style>
|
||||||
|
#ptr-screen {
|
||||||
|
position: fixed; inset: 0;
|
||||||
|
display: flex; flex-direction: column;
|
||||||
|
align-items: center; justify-content: center;
|
||||||
|
font-family: sans-serif; text-align: center;
|
||||||
|
padding: 2rem; touch-action: none;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
#ptr-icon {
|
||||||
|
font-size: 2rem; margin-bottom: 1rem;
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s ease;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
#ptr-label {
|
||||||
|
font-size: 0.9rem; opacity: 0.5;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
#ptr-indicator {
|
||||||
|
color: var(--text);
|
||||||
|
position: fixed; top: 5vh; left: 0; right: 0;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
padding-top: env(safe-area-inset-top);
|
||||||
|
height: 0; overflow: hidden;
|
||||||
|
transition: height 0.1s ease;
|
||||||
|
font-size: 0.8rem; opacity: 0.6; gap: 0.4rem;
|
||||||
|
}
|
||||||
|
@keyframes spin { to { transform: rotate(360deg) } }
|
||||||
|
.spinning { animation: spin 0.6s linear infinite }
|
||||||
|
</style>
|
||||||
|
<div id="ptr-indicator">
|
||||||
|
<span id="ptr-arrow">↓</span>
|
||||||
|
<span id="ptr-hint">Pull to retry</span>
|
||||||
|
</div>
|
||||||
|
<div id="ptr-screen">
|
||||||
|
<div id="ptr-icon">⚠️</div>
|
||||||
|
<p style="margin:0;font-size:1.1rem;font-weight:600">No connection</p>
|
||||||
|
<p id="ptr-label">Could not reach the server.<br>Pull down to try again.</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
|
||||||
|
const THRESHOLD = 90
|
||||||
|
let startY = 0, dragging = false
|
||||||
|
|
||||||
|
document.addEventListener('touchstart', e => {
|
||||||
|
startY = e.touches[0].clientY
|
||||||
|
dragging = true
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', e => {
|
||||||
|
if (!dragging) return
|
||||||
|
const dy = Math.max(0, e.touches[0].clientY - startY)
|
||||||
|
const pull = Math.min(dy, THRESHOLD * 1.5)
|
||||||
|
const progress = Math.min(pull / THRESHOLD, 1)
|
||||||
|
|
||||||
|
document.getElementById('ptr-screen').style.transform = `translateY(${pull * 0.4}px)`
|
||||||
|
document.getElementById('ptr-indicator').style.height = (pull * 0.6) + 'px'
|
||||||
|
document.getElementById('ptr-arrow').style.transform = `rotate(${progress * 180}deg)`
|
||||||
|
document.getElementById('ptr-hint').textContent = progress >= 1 ? 'Release to retry' : 'Pull to retry'
|
||||||
|
document.getElementById('ptr-icon').style.opacity = 0.4 + progress * 0.6
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener('touchend', e => {
|
||||||
|
if (!dragging) return
|
||||||
|
dragging = false
|
||||||
|
const dy = e.changedTouches[0].clientY - startY
|
||||||
|
if (dy >= THRESHOLD) {
|
||||||
|
document.getElementById('ptr-arrow').textContent = '↻'
|
||||||
|
document.getElementById('ptr-arrow').classList.add('spinning')
|
||||||
|
document.getElementById('ptr-hint').textContent = 'Retrying…'
|
||||||
|
setTimeout(() => location.reload(), 400)
|
||||||
|
} else {
|
||||||
|
document.getElementById('ptr-screen').style.transform = ''
|
||||||
|
document.getElementById('ptr-indicator').style.height = '0'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<meta name="theme-color" content="#31d53d" />
|
<meta name="theme-color" content="#31d53d" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import "./Home.js"
|
|
||||||
Home()
|
|
||||||
document.body.style.backgroundColor = "var(--main)"
|
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
"start_url": "index.html",
|
"start_url": "index.html",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"icons": [{
|
"icons": [{
|
||||||
"src": "_/imgs/logo.png",
|
"src": "_/icons/logo.svg",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/svg"
|
||||||
}],
|
}],
|
||||||
"background_color": "#31d53d",
|
"background_color": "#31d53d",
|
||||||
"theme_color": "#31d53d"
|
"theme_color": "#31d53d"
|
||||||
|
|||||||
53
src/util.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { PushNotifications } from '@capacitor/push-notifications';
|
||||||
|
import { Preferences } from '@capacitor/preferences';
|
||||||
|
import { Filesystem, Directory } from '@capacitor/filesystem';
|
||||||
|
import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
||||||
|
import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';
|
||||||
|
import { Geolocation } from '@capacitor/geolocation';
|
||||||
|
import { SplashScreen } from '@capacitor/splash-screen';
|
||||||
|
|
||||||
|
window.capacitor = {
|
||||||
|
Preferences,
|
||||||
|
PushNotifications,
|
||||||
|
Filesystem,
|
||||||
|
Directory,
|
||||||
|
Haptics,
|
||||||
|
ImpactStyle,
|
||||||
|
Camera,
|
||||||
|
CameraResultType,
|
||||||
|
CameraSource,
|
||||||
|
Geolocation,
|
||||||
|
SplashScreen,
|
||||||
|
}
|
||||||
|
|
||||||
|
const env = import.meta.env
|
||||||
|
|
||||||
|
window.util = class util {
|
||||||
|
|
||||||
|
static HOST = env.VITE_API_URL
|
||||||
|
static PushNotifications = PushNotifications
|
||||||
|
static Preferences = Preferences
|
||||||
|
|
||||||
|
static async authFetch(url, options = {}) {
|
||||||
|
const { value: token } = await Preferences.get({ key: 'auth_token' });
|
||||||
|
|
||||||
|
return fetch(url, {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...options.headers,
|
||||||
|
'Authorization': `Bearer ${token}`,
|
||||||
|
'X-Client': 'mobile'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async removeAuthToken() {
|
||||||
|
await Preferences.remove({ key: 'auth_token'})
|
||||||
|
}
|
||||||
|
|
||||||
|
static cssVariable(value) {
|
||||||
|
return getComputedStyle(document.documentElement)
|
||||||
|
.getPropertyValue("--" + value)
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,45 @@ export default defineConfig({
|
|||||||
outDir: '../dist',
|
outDir: '../dist',
|
||||||
minify: false,
|
minify: false,
|
||||||
emptyOutDir: true,
|
emptyOutDir: true,
|
||||||
|
sourcemap: true,
|
||||||
|
target: 'esnext' // modern version of browsers, allows top-level await
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
proxy: {
|
||||||
|
"/ws": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true
|
||||||
|
},
|
||||||
|
"/profile/upload-image": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
},
|
||||||
|
"/api": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
},
|
||||||
|
"/db": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
},
|
||||||
|
"/apps": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
},
|
||||||
|
"/auth": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
},
|
||||||
|
"/@server": {
|
||||||
|
target: "http://localhost:10002",
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
},
|
||||||
host: true,
|
host: true,
|
||||||
allowedHosts: ['sam.local'],
|
allowedHosts: ['sam.local'],
|
||||||
|
},
|
||||||
|
esbuild: {
|
||||||
|
keepNames: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||