Compare commits
79 Commits
edd91be047
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5304ab1d6d | |||
|
|
69469fa2ad | ||
|
|
142d4a3fc3 | ||
|
|
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 | ||
| c09b08a474 | |||
|
|
7f3f266d52 | ||
|
|
fd27ac9c69 | ||
|
|
5b0f69b7aa | ||
|
|
2d71dd0245 | ||
|
|
7a3dabc9aa | ||
|
|
aba685fb72 | ||
|
|
f80b0b1bf3 | ||
|
|
a0adeecb13 |
1
.gitignore
vendored
@@ -5,3 +5,4 @@ node_modules/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.sourcemaps
|
.sourcemaps
|
||||||
dist/
|
dist/
|
||||||
|
package-lock.json
|
||||||
27
README.md
@@ -1,27 +0,0 @@
|
|||||||
## Created with Capacitor Create App
|
|
||||||
|
|
||||||
This app was created using [`@capacitor/create-app`](https://github.com/ionic-team/create-capacitor-app),
|
|
||||||
and comes with a very minimal shell for building an app.
|
|
||||||
|
|
||||||
### Running this example
|
|
||||||
|
|
||||||
To run the provided example, you can use `npm start` command.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
### Running iOS
|
|
||||||
|
|
||||||
https://capacitorjs.com/docs/ios#adding-the-ios-platform
|
|
||||||
|
|
||||||
npm install @capacitor/ios
|
|
||||||
npx cap add ios
|
|
||||||
npx cap open ios
|
|
||||||
|
|
||||||
To Rerun:
|
|
||||||
npm run build && npx cap copy ios
|
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"appId": "so.blockcatcher.app",
|
"appId": "so.forum.app",
|
||||||
"appName": "Blockcatcher",
|
"appName": "Forum",
|
||||||
"webDir": "dist",
|
"webDir": "dist",
|
||||||
|
"ios": {
|
||||||
|
"allowsBackForwardNavigationGestures": true
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"url": "http://sam.local:5173",
|
||||||
|
"cleartext": true
|
||||||
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"SplashScreen": {
|
"SplashScreen": {
|
||||||
"launchAutoHide": false
|
"launchAutoHide": false
|
||||||
|
|||||||
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)
|
||||||
|
```
|
||||||
@@ -14,10 +14,37 @@
|
|||||||
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
|
504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; };
|
||||||
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
|
504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; };
|
||||||
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; };
|
||||||
|
5ADE813A2FAD0ACB008DDDE2 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ADE81392FAD0ACB008DDDE2 /* NotificationService.swift */; };
|
||||||
|
5ADE813E2FAD0ACB008DDDE2 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 5ADE81372FAD0ACA008DDDE2 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
|
A084ECDBA7D38E1E42DFC39D /* Pods_App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
5ADE813C2FAD0ACB008DDDE2 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 504EC2FC1FED79650016851F /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 5ADE81362FAD0ACA008DDDE2;
|
||||||
|
remoteInfo = NotificationService;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
5ADE813F2FAD0ACB008DDDE2 /* Embed Foundation Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
5ADE813E2FAD0ACB008DDDE2 /* NotificationService.appex in Embed Foundation Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed Foundation Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase 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; };
|
||||||
@@ -27,6 +54,9 @@
|
|||||||
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
|
50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = "<group>"; };
|
||||||
|
5ADE81372FAD0ACA008DDDE2 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
5ADE81392FAD0ACB008DDDE2 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
|
||||||
|
5ADE813B2FAD0ACB008DDDE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
AF277DCFFFF123FFC6DF26C7 /* Pods_App.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.release.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App.debug.xcconfig"; path = "Pods/Target Support Files/Pods-App/Pods-App.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
@@ -41,6 +71,13 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5ADE81342FAD0ACA008DDDE2 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@@ -56,6 +93,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
504EC3061FED79650016851F /* App */,
|
504EC3061FED79650016851F /* App */,
|
||||||
|
5ADE81382FAD0ACB008DDDE2 /* NotificationService */,
|
||||||
504EC3051FED79650016851F /* Products */,
|
504EC3051FED79650016851F /* Products */,
|
||||||
7F8756D8B27F46E3366F6CEA /* Pods */,
|
7F8756D8B27F46E3366F6CEA /* Pods */,
|
||||||
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
|
27E2DDA53C4D2A4D1A88CE4A /* Frameworks */,
|
||||||
@@ -66,6 +104,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
504EC3041FED79650016851F /* App.app */,
|
504EC3041FED79650016851F /* App.app */,
|
||||||
|
5ADE81372FAD0ACA008DDDE2 /* NotificationService.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -73,6 +112,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 */,
|
||||||
@@ -85,6 +125,15 @@
|
|||||||
path = App;
|
path = App;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
5ADE81382FAD0ACB008DDDE2 /* NotificationService */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5ADE81392FAD0ACB008DDDE2 /* NotificationService.swift */,
|
||||||
|
5ADE813B2FAD0ACB008DDDE2 /* Info.plist */,
|
||||||
|
);
|
||||||
|
path = NotificationService;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7F8756D8B27F46E3366F6CEA /* Pods */ = {
|
7F8756D8B27F46E3366F6CEA /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -107,23 +156,42 @@
|
|||||||
504EC3021FED79650016851F /* Resources */,
|
504EC3021FED79650016851F /* Resources */,
|
||||||
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
9592DBEFFC6D2A0C8D5DEB22 /* [CP] Embed Pods Frameworks */,
|
||||||
E3424294FACA667401D6F46C /* [CP] Copy Pods Resources */,
|
E3424294FACA667401D6F46C /* [CP] Copy Pods Resources */,
|
||||||
|
5ADE813F2FAD0ACB008DDDE2 /* Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
5ADE813D2FAD0ACB008DDDE2 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = App;
|
name = App;
|
||||||
productName = App;
|
productName = App;
|
||||||
productReference = 504EC3041FED79650016851F /* App.app */;
|
productReference = 504EC3041FED79650016851F /* App.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
|
5ADE81362FAD0ACA008DDDE2 /* NotificationService */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 5ADE81422FAD0ACB008DDDE2 /* Build configuration list for PBXNativeTarget "NotificationService" */;
|
||||||
|
buildPhases = (
|
||||||
|
5ADE81332FAD0ACA008DDDE2 /* Sources */,
|
||||||
|
5ADE81342FAD0ACA008DDDE2 /* Frameworks */,
|
||||||
|
5ADE81352FAD0ACA008DDDE2 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = NotificationService;
|
||||||
|
productName = NotificationService;
|
||||||
|
productReference = 5ADE81372FAD0ACA008DDDE2 /* NotificationService.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
/* Begin PBXProject section */
|
||||||
504EC2FC1FED79650016851F /* Project object */ = {
|
504EC2FC1FED79650016851F /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0920;
|
LastSwiftUpdateCheck = 1500;
|
||||||
LastUpgradeCheck = 0920;
|
LastUpgradeCheck = 0920;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
504EC3031FED79650016851F = {
|
504EC3031FED79650016851F = {
|
||||||
@@ -131,6 +199,10 @@
|
|||||||
LastSwiftMigration = 1100;
|
LastSwiftMigration = 1100;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
|
5ADE81362FAD0ACA008DDDE2 = {
|
||||||
|
CreatedOnToolsVersion = 15.0;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
|
buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */;
|
||||||
@@ -147,6 +219,7 @@
|
|||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
504EC3031FED79650016851F /* App */,
|
504EC3031FED79650016851F /* App */,
|
||||||
|
5ADE81362FAD0ACA008DDDE2 /* NotificationService */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@@ -165,6 +238,13 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5ADE81352FAD0ACA008DDDE2 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
@@ -227,8 +307,24 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
5ADE81332FAD0ACA008DDDE2 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
5ADE813A2FAD0ACB008DDDE2 /* NotificationService.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
5ADE813D2FAD0ACB008DDDE2 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 5ADE81362FAD0ACA008DDDE2 /* NotificationService */;
|
||||||
|
targetProxy = 5ADE813C2FAD0ACB008DDDE2 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
504EC30B1FED79650016851F /* Main.storyboard */ = {
|
504EC30B1FED79650016851F /* Main.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
@@ -360,16 +456,18 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
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;
|
||||||
@@ -381,15 +479,17 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
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;
|
||||||
@@ -397,6 +497,72 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
5ADE81402FAD0ACB008DDDE2 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum.NotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
5ADE81412FAD0ACB008DDDE2 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 53DK57C7ZF;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = NotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum.NotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
@@ -418,6 +584,15 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
5ADE81422FAD0ACB008DDDE2 /* Build configuration list for PBXNativeTarget "NotificationService" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
5ADE81402FAD0ACB008DDDE2 /* Debug */,
|
||||||
|
5ADE81412FAD0ACB008DDDE2 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
};
|
};
|
||||||
rootObject = 504EC2FC1FED79650016851F /* Project object */;
|
rootObject = 504EC2FC1FED79650016851F /* Project object */;
|
||||||
|
|||||||
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.8">
|
||||||
|
<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/>
|
||||||
|
|||||||
13
ios/App/NotificationService/Info.plist
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?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>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.usernotifications.service</string>
|
||||||
|
<key>NSExtensionPrincipalClass</key>
|
||||||
|
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
49
ios/App/NotificationService/NotificationService.swift
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// NotificationService.swift
|
||||||
|
// NotificationService
|
||||||
|
//
|
||||||
|
// Created by Matias Carulli on 5/7/26.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UserNotifications
|
||||||
|
|
||||||
|
class NotificationService: UNNotificationServiceExtension {
|
||||||
|
|
||||||
|
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||||
|
var bestAttemptContent: UNMutableNotificationContent?
|
||||||
|
|
||||||
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||||
|
self.contentHandler = contentHandler
|
||||||
|
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||||
|
|
||||||
|
guard
|
||||||
|
let content = bestAttemptContent,
|
||||||
|
let imageUrlString = request.content.userInfo["imageUrl"] as? String,
|
||||||
|
let imageUrl = URL(string: imageUrlString)
|
||||||
|
else {
|
||||||
|
contentHandler(request.content)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
URLSession.shared.downloadTask(with: imageUrl) { location, _, error in
|
||||||
|
defer { contentHandler(content) }
|
||||||
|
guard let location = location, error == nil else { return }
|
||||||
|
|
||||||
|
let tmpFile = URL(fileURLWithPath: NSTemporaryDirectory())
|
||||||
|
.appendingPathComponent(imageUrl.lastPathComponent)
|
||||||
|
|
||||||
|
try? FileManager.default.moveItem(at: location, to: tmpFile)
|
||||||
|
|
||||||
|
if let attachment = try? UNNotificationAttachment(identifier: "avatar", url: tmpFile) {
|
||||||
|
content.attachments = [attachment]
|
||||||
|
}
|
||||||
|
}.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func serviceExtensionTimeWillExpire() {
|
||||||
|
if let contentHandler = contentHandler, let content = bestAttemptContent {
|
||||||
|
contentHandler(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,9 +12,14 @@ 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'
|
||||||
|
pod 'NotnotsamuelCapacitorSwipeBack', :path => '../../node_modules/@notnotsamuel/capacitor-swipe-back'
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'App' do
|
target 'App' do
|
||||||
|
|||||||
@@ -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,29 @@ 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)
|
||||||
|
- NotnotsamuelCapacitorSwipeBack (3.0.2):
|
||||||
|
- Capacitor
|
||||||
|
|
||||||
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`)"
|
||||||
|
- "NotnotsamuelCapacitorSwipeBack (from `../../node_modules/@notnotsamuel/capacitor-swipe-back`)"
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- Google-Maps-iOS-Utils
|
- Google-Maps-iOS-Utils
|
||||||
- GoogleMaps
|
- GoogleMaps
|
||||||
|
- IONFilesystemLib
|
||||||
- IONGeolocationLib
|
- IONGeolocationLib
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@@ -43,24 +61,40 @@ 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"
|
||||||
|
NotnotsamuelCapacitorSwipeBack:
|
||||||
|
:path: "../../node_modules/@notnotsamuel/capacitor-swipe-back"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
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
|
||||||
|
NotnotsamuelCapacitorSwipeBack: 07a8985928db83b1d62a1d596246db466e69d149
|
||||||
|
|
||||||
PODFILE CHECKSUM: 1f8c41a3cb5e4540693adb6a47064e328eec261d
|
PODFILE CHECKSUM: d7fbdcfecbb81edc39c9975b338d5d15e186424b
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.15.2
|
||||||
|
|||||||
2275
package-lock.json
generated
15
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,17 @@
|
|||||||
"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",
|
||||||
|
"@notnotsamuel/capacitor-swipe-back": "^3.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "latest",
|
"@capacitor/cli": "latest",
|
||||||
|
|||||||
74
readme.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
## Run in Browser
|
||||||
|
|
||||||
|
```npm run start```
|
||||||
|
|
||||||
|
## Install Native Tools
|
||||||
|
|
||||||
|
https://capacitorjs.com/docs/ios#adding-the-ios-platform
|
||||||
|
|
||||||
|
npm install @capacitor/ios
|
||||||
|
npx cap add ios
|
||||||
|
|
||||||
|
## Run On Device
|
||||||
|
|
||||||
|
To Open XCode:
|
||||||
|
npx cap open ios
|
||||||
|
|
||||||
|
Run this command to rebuild for iOS
|
||||||
|
npm run build && npx cap copy ios
|
||||||
|
|
||||||
|
If getting black screen:
|
||||||
|
npx cap sync iOS
|
||||||
|
|
||||||
|
|
||||||
|
## iOS:
|
||||||
|
|
||||||
|
### Browser: Dev Front and Dev Back (localhost)
|
||||||
|
This option should be at the top level of capacitor.config.json
|
||||||
|
"server": {
|
||||||
|
"url": "http://sam.local:5173",
|
||||||
|
"cleartext": true
|
||||||
|
},
|
||||||
|
|
||||||
|
### Browser: Prod Front and Prod Back
|
||||||
|
Run:
|
||||||
|
vite build
|
||||||
|
npx serve dist
|
||||||
|
|
||||||
|
If you need to login again:
|
||||||
|
run localStorage.clear() in the browser dev tools console and then refresh the page.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## iOS:
|
||||||
|
|
||||||
|
### Dev Front, Dev Back (localhost)
|
||||||
|
This option should be at the top level of capacitor.config.json
|
||||||
|
"server": {
|
||||||
|
"url": "http://sam.local:5173",
|
||||||
|
"cleartext": true
|
||||||
|
},
|
||||||
|
|
||||||
|
### Dev Front, Prod Back (frm.so)
|
||||||
|
Add "https://frm.so" to VITE_API_URL in .env.development
|
||||||
|
|
||||||
|
### Prod Front, Prod Back (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
|
||||||
1186
src/_/code/quill.js
@@ -1,12 +0,0 @@
|
|||||||
:root {
|
|
||||||
--main: #AEBDFF;
|
|
||||||
--accent: #60320c;
|
|
||||||
--text: #340000;
|
|
||||||
--yellow: #f1f3c3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 99 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 |
@@ -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,12 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
134
src/index.html
@@ -2,28 +2,130 @@
|
|||||||
<html lang="en" dir="ltr">
|
<html lang="en" dir="ltr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Blockcatcher</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/runner.svg" />
|
|
||||||
<link rel="manifest" href="./manifest.json" />
|
<link rel="manifest" href="./manifest.json" />
|
||||||
<link rel="stylesheet" href="./_/code/styles.css" />
|
<link rel="stylesheet" href="" />
|
||||||
<script src="./_/code/quill.js"></script>
|
<script>window.config = { UI: 'https://frm.so', SERVER: 'https://frm.so' }</script>
|
||||||
<script type="module" src="./index.js"></script>
|
<script type="module">
|
||||||
|
await import('./mobileutil.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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendStylesheet(href, { replaceExisting = false } = {}) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (replaceExisting) {
|
||||||
|
document.querySelector('link[rel="stylesheet"]')?.remove();
|
||||||
|
}
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = href;
|
||||||
|
link.onload = resolve;
|
||||||
|
link.onerror = reject;
|
||||||
|
document.head.appendChild(link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await appendStylesheet(`${window.config.UI}/_/code/shared.css`, { replaceExisting: true });
|
||||||
|
await appendScript(window.config.UI + '/_/code/quill.js')
|
||||||
|
await appendScript(window.config.UI + '/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 "./js/Home.js"
|
|
||||||
Home()
|
|
||||||
document.body.style.backgroundColor = "var(--main)"
|
|
||||||
197
src/js/Home.js
@@ -1,197 +0,0 @@
|
|||||||
class Home extends Shadow {
|
|
||||||
|
|
||||||
tracking = false
|
|
||||||
logs = []
|
|
||||||
timer = null
|
|
||||||
|
|
||||||
async startTracking() {
|
|
||||||
if (!navigator.geolocation) {
|
|
||||||
alert("Geolocation is not supported by your browser.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tracking = true
|
|
||||||
|
|
||||||
navigator.geolocation.requestPermission?.() || Promise.resolve('granted');
|
|
||||||
|
|
||||||
const permission = await new Promise((resolve) => {
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
|
||||||
() => resolve('granted'),
|
|
||||||
() => resolve('denied')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (permission === 'denied') {
|
|
||||||
alert("Location permission required");
|
|
||||||
this.tracking = false
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timer = setInterval(async () => {
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
|
||||||
async (pos) => {
|
|
||||||
const { latitude, longitude } = pos.coords;
|
|
||||||
const now = new Date();
|
|
||||||
const log = `${now.toISOString()} — (${latitude}, ${longitude})`;
|
|
||||||
const timestamp = this.formatCentralTime(now);
|
|
||||||
|
|
||||||
this.logs = [log, ...this.logs]
|
|
||||||
|
|
||||||
this.updateLogs()
|
|
||||||
await this.sendLocation(latitude, longitude, timestamp);
|
|
||||||
},
|
|
||||||
(err) => console.error("Location error:", err),
|
|
||||||
{ enableHighAccuracy: true }
|
|
||||||
);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
this.timer = timer
|
|
||||||
}
|
|
||||||
|
|
||||||
stopTracking() {
|
|
||||||
if (this.timer) {
|
|
||||||
clearInterval(this.timer);
|
|
||||||
this.timer = null;
|
|
||||||
this.tracking = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
ZStack(() => {
|
|
||||||
// Title bar
|
|
||||||
HStack(() => {
|
|
||||||
img("./_/icons/runner.svg", "2em", "2em")
|
|
||||||
p("San Marcos, TX")
|
|
||||||
.fontSize(1.2, em)
|
|
||||||
img("./_/icons/hamburger.svg", "2em", "2em")
|
|
||||||
})
|
|
||||||
.gap(15, vw)
|
|
||||||
.position("fixed")
|
|
||||||
.top(0)
|
|
||||||
.left(0)
|
|
||||||
.width(100, vw)
|
|
||||||
.paddingTop(2, em)
|
|
||||||
.paddingBottom(2, em)
|
|
||||||
.borderBottom("0.1rem solid var(--text)")
|
|
||||||
.backgroundColor("var(--yellow)")
|
|
||||||
.fontWeight("bold")
|
|
||||||
.display("flex")
|
|
||||||
.alignItems("center")
|
|
||||||
.justifyContent("center")
|
|
||||||
.zIndex(10)
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
button(() => {
|
|
||||||
if(this.tracking) {
|
|
||||||
Rectangle("48%", "48%")
|
|
||||||
.fill("#264B61")
|
|
||||||
.stroke("0.2em", "black")
|
|
||||||
} else {
|
|
||||||
Triangle("58%", "58%")
|
|
||||||
.fill("#9F292B")
|
|
||||||
.stroke("0.2em", "black")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.attr({"id": "playButton"})
|
|
||||||
.width(120, px)
|
|
||||||
.height(120, px)
|
|
||||||
.x(50, vw).y(50, vh)
|
|
||||||
.center()
|
|
||||||
.borderRadius(50, "%")
|
|
||||||
.backgroundColor(this.tracking ? "#CD593E" : "#A6EABD")
|
|
||||||
.border("0.2em solid black")
|
|
||||||
.cursor("pointer")
|
|
||||||
.display("flex")
|
|
||||||
.alignItems("center")
|
|
||||||
.justifyContent("center")
|
|
||||||
.onTap(() => {
|
|
||||||
console.log("tapped")
|
|
||||||
if (this.tracking) {
|
|
||||||
this.stopTracking();
|
|
||||||
this.rerender()
|
|
||||||
} else {
|
|
||||||
this.startTracking();
|
|
||||||
this.rerender()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
VStack(() => {
|
|
||||||
this.logs.map(log =>
|
|
||||||
div(log)
|
|
||||||
.paddingHorizontal("8px")
|
|
||||||
.paddingVertical("12px")
|
|
||||||
.backgroundColor("rgba(255,255,255,0.9)")
|
|
||||||
.borderRadius(6, px)
|
|
||||||
.marginBottom(6, px)
|
|
||||||
.fontSize(0.9, rem)
|
|
||||||
.color("#222")
|
|
||||||
.fontFamily("monospace")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.attr({"id": "logList"})
|
|
||||||
.flex(1)
|
|
||||||
.overflowY("auto")
|
|
||||||
.paddingHorizontal(16, px)
|
|
||||||
})
|
|
||||||
.marginTop(7, em)
|
|
||||||
})
|
|
||||||
.overflowX("hidden")
|
|
||||||
.width(100, vw)
|
|
||||||
.height(100, vh)
|
|
||||||
.display("block")
|
|
||||||
.margin(0)
|
|
||||||
.color("var(--text)")
|
|
||||||
.fontFamily("Arial")
|
|
||||||
}
|
|
||||||
|
|
||||||
showTracking() {
|
|
||||||
this.$("#playButton").rerender()
|
|
||||||
this.$("#playButton").style.backgroundColor = this.tracking ? "#CD593E" : "#A6EABD"
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLogs() {
|
|
||||||
let list = this.$("#logList")
|
|
||||||
list.rerender()
|
|
||||||
list.attr({"id": "logList"})
|
|
||||||
}
|
|
||||||
|
|
||||||
formatCentralTime(date) {
|
|
||||||
return new Intl.DateTimeFormat('en-US', {
|
|
||||||
timeZone: 'America/Chicago',
|
|
||||||
month: '2-digit',
|
|
||||||
day: '2-digit',
|
|
||||||
year: '2-digit',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: '2-digit',
|
|
||||||
second: '2-digit',
|
|
||||||
hour12: true
|
|
||||||
})
|
|
||||||
.format(date)
|
|
||||||
.replace(/,/, '') // "04/05/25, 2:30:00 PM" → "04/05/25 2:30:00 PM"
|
|
||||||
.replace(/\//g, '.') // → "04.05.25 2:30:00 PM"
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(' pm', 'pm')
|
|
||||||
.replace(' am', 'am');
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendLocation(lat, lon, timestamp) {
|
|
||||||
try {
|
|
||||||
const resp = await fetch('http://localhost:3008/api/location', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
name: "Freddy Krueger",
|
|
||||||
latitude: lat,
|
|
||||||
longitude: lon,
|
|
||||||
timestamp
|
|
||||||
})
|
|
||||||
});
|
|
||||||
if (!resp.ok) throw new Error(resp.status);
|
|
||||||
console.log('Location sent');
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to send location:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
register(Home)
|
|
||||||
@@ -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"
|
||||||
|
|||||||
43
src/mobileutil.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
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';
|
||||||
|
import { CapacitorSwipeBackPlugin } from '@notnotsamuel/capacitor-swipe-back';
|
||||||
|
|
||||||
|
window.capacitor = {
|
||||||
|
Preferences,
|
||||||
|
PushNotifications,
|
||||||
|
Filesystem,
|
||||||
|
Directory,
|
||||||
|
Haptics,
|
||||||
|
ImpactStyle,
|
||||||
|
Camera,
|
||||||
|
CameraResultType,
|
||||||
|
CameraSource,
|
||||||
|
Geolocation,
|
||||||
|
SplashScreen,
|
||||||
|
CapacitorSwipeBackPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
window.mobileUtil = class mobileUtil {
|
||||||
|
|
||||||
|
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'})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||