From d107d68bcc3cb4238015c96484d3f3e6fa2f7f99 Mon Sep 17 00:00:00 2001 From: metacryst Date: Thu, 26 Mar 2026 02:32:59 -0500 Subject: [PATCH] push notifications working, server functions coming from backend --- ios/App/App.xcodeproj/project.pbxproj | 8 +- ios/App/App/App.entitlements | 8 ++ ios/App/App/AppDelegate.swift | 8 ++ ios/App/App/Info.plist | 8 +- src/Profile/Profile.js | 14 +-- src/_/code/bridge/bridge.js | 34 ------ src/_/code/bridge/server.js | 10 -- src/_/code/bridge/serverFunctions.js | 143 -------------------------- src/index.js | 35 +++++-- 9 files changed, 60 insertions(+), 208 deletions(-) create mode 100644 ios/App/App/App.entitlements delete mode 100644 src/_/code/bridge/bridge.js delete mode 100644 src/_/code/bridge/server.js delete mode 100644 src/_/code/bridge/serverFunctions.js diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index cb67f70..5515da2 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 22352DD22F74F93C0052EF07 /* App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = App.entitlements; sourceTree = ""; }; 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; 504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -73,6 +74,7 @@ 504EC3061FED79650016851F /* App */ = { isa = PBXGroup; children = ( + 22352DD22F74F93C0052EF07 /* App.entitlements */, 50379B222058CBB4000EE86E /* capacitor.config.json */, 504EC3071FED79650016851F /* AppDelegate.swift */, 504EC30B1FED79650016851F /* Main.storyboard */, @@ -361,6 +363,7 @@ baseConfigurationReference = FC68EB0AF532CFC21C3344DD /* Pods-App.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = App/App.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 53DK57C7ZF; @@ -369,7 +372,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; - PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app; + PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_VERSION = 5.0; @@ -382,6 +385,7 @@ baseConfigurationReference = AF51FD2D460BCFE21FA515B2 /* Pods-App.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = App/App.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 53DK57C7ZF; @@ -389,7 +393,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = so.hyperia.app; + PRODUCT_BUNDLE_IDENTIFIER = russell.sam.forum; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; SWIFT_VERSION = 5.0; diff --git a/ios/App/App/App.entitlements b/ios/App/App/App.entitlements new file mode 100644 index 0000000..903def2 --- /dev/null +++ b/ios/App/App/App.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift index 1ae82c4..e74f63f 100644 --- a/ios/App/App/AppDelegate.swift +++ b/ios/App/App/AppDelegate.swift @@ -73,5 +73,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // tracking app url opens, make sure to keep this call 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) + } } diff --git a/ios/App/App/Info.plist b/ios/App/App/Info.plist index 0b9c151..6e0a2a3 100644 --- a/ios/App/App/Info.plist +++ b/ios/App/App/Info.plist @@ -24,11 +24,15 @@ NSAppTransportSecurity - NSAllowsLocalNetworking - NSAllowsArbitraryLoads + NSAllowsLocalNetworking + + UIBackgroundModes + + remote-notification + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/src/Profile/Profile.js b/src/Profile/Profile.js index d9f60eb..f0bbc3f 100644 --- a/src/Profile/Profile.js +++ b/src/Profile/Profile.js @@ -1,4 +1,3 @@ -import server from "../_/code/bridge/serverFunctions"; import util from "../util"; css(` @@ -150,12 +149,13 @@ class Profile extends Shadow { .onSubmit(async (e) => { e.preventDefault(); const newBio = new FormData(e.target).get("bioinput"); - if (newBio.trim() !== this.profile.bio.trim()) { - const result = await server.editBio(newBio, this.profile.id) - const { bio, updated_at } = result.data - global.profile.bio = bio - global.profile.updated_at = updated_at - this.profile = global.profile + console.log(this.profile) + if (newBio.trim() !== this.profile.bio?.trim()) { + const result = await server.editBio(newBio, this.profile.id) + const { bio, updated_at } = result.data + global.profile.bio = bio + global.profile.updated_at = updated_at + this.profile = global.profile } }) }) diff --git a/src/_/code/bridge/bridge.js b/src/_/code/bridge/bridge.js deleted file mode 100644 index 8af6082..0000000 --- a/src/_/code/bridge/bridge.js +++ /dev/null @@ -1,34 +0,0 @@ -export const IS_NODE = - typeof process !== "undefined" && - process.versions?.node != null - -async function bridgeSend(name, args) { - // Example browser implementation: send function call to server - const res = await global.Socket.send({ - name: name, - args: args - }) - - return res -} - -/** - * Wraps an object of functions so that: - * - Node calls the real function - * - Browser calls bridgeSend - */ -export function createBridge(funcs) { - return new Proxy(funcs, { - get(target, prop) { - const orig = target[prop] - - return function (...args) { - if (IS_NODE) { - return orig(...args) - } else { - return bridgeSend(prop, args) - } - } - } - }) -} diff --git a/src/_/code/bridge/server.js b/src/_/code/bridge/server.js deleted file mode 100644 index cc309ce..0000000 --- a/src/_/code/bridge/server.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createBridge, IS_NODE } from "./bridge.js" - -let handlers = {} - -if (IS_NODE) { - const mod = await import("./serverFunctions.js") - handlers = mod.default -} - -export default createBridge(handlers) \ No newline at end of file diff --git a/src/_/code/bridge/serverFunctions.js b/src/_/code/bridge/serverFunctions.js deleted file mode 100644 index 41da64e..0000000 --- a/src/_/code/bridge/serverFunctions.js +++ /dev/null @@ -1,143 +0,0 @@ -const handlers = { - async getStripeProfile(networkId) { - return global.payments.getProfile(networkId) - }, - - async addEvent(newEvent, networkId, creatorId) { - try { - return await global.db.events.add(newEvent, networkId, creatorId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async editEvent(id, updatedEvent, networkId, userId) { - try { - return await global.db.events.edit(id, updatedEvent, networkId, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async deleteEvent(id, networkId, userId) { - try { - return await global.db.events.delete(id, networkId, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getEvent(id) { - try { - return global.db.events.getById(id) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getEvents(networkId) { - try { - return global.db.events.getByNetwork(networkId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async addJob(newJob, networkId, creatorId) { - try { - return await global.db.jobs.add(newJob, networkId, creatorId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async editJob(id, updatedJob, networkId, userId) { - try { - return await global.db.jobs.edit(id, updatedJob, networkId, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async deleteJob(id, networkId, userId) { - try { - return await global.db.jobs.delete(id, networkId, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getJob(id) { - try { - return await global.db.jobs.getById(id) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getJobs(networkId) { - try { - return global.db.jobs.getByNetwork(networkId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async addAnnouncement(text, networkId, userId) { - try { - return await global.db.announcements.add(text, networkId, userId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async editAnnouncement(newAnnouncement, userId) { - try { - return await global.db.announcements.edit(newAnnouncement, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async deleteAnnouncement(id, userId) { - try { - return await global.db.announcements.delete(id, userId); - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getAnnouncement(id) { - try { - return global.db.announcements.getById(id) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getAnnouncements(networkId) { - try { - return global.db.announcements.getByNetwork(networkId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async getUserAnnouncements(userId) { - try { - return global.db.announcements.getByCreator(userId) - } catch (e) { - return { status: e.status, error: e.message } - } - }, - - async editBio(newBio, userId) { - try { - return global.db.members.editBio(newBio, userId) - } catch (e) { - return { status: e.status, error: e.message } - } - } -} - -export default handlers \ No newline at end of file diff --git a/src/index.js b/src/index.js index 988d0c0..40d6207 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,4 @@ import { PushNotifications } from '@capacitor/push-notifications'; - -import server from './_/code/bridge/server.js' import Socket from "/_/code/ws/Socket.js" import "./Home/Home.js" import "./Home/AuthPage/AuthPage.js" @@ -160,31 +158,44 @@ let Global = class { } async setupPushNotifications() { - const permission = await PushNotifications.requestPermissions(); - - if (permission.receive === 'granted') { - await PushNotifications.register(); - } - PushNotifications.addListener('registration', async (token) => { console.log('Device token:', token.value) const stored = localStorage.getItem('deviceToken') if (stored === token.value) return; + console.log("new push token") await server.updatePushToken(token.value) localStorage.setItem('deviceToken', token.value) }); PushNotifications.addListener('registrationError', (error) => { - console.error('Registration error:', error) + console.error('Registration error:', JSON.stringify(error)) }); PushNotifications.addListener('pushNotificationReceived', (notification) => { console.log('Notification received:', notification) }); + + PushNotifications.addListener('pushNotificationActionPerformed', (action) => { + console.log('Notification tapped:', action.notification) + // navigate somewhere based on action.notification.data + }); + + const permission = await PushNotifications.requestPermissions(); + if (permission.receive === 'granted') { + await PushNotifications.register(); + console.log('after registter:') + } } - constructor() { + async init() { + try { + const module = await import(`${util.HOST}/@server/server.js`); + window.server = module.default; + } catch(E) { + console.error(E) + } + this.setupPushNotifications() window.addEventListener("navigate", this.onNavigate) @@ -201,6 +212,10 @@ let Global = class { } }) } + + constructor() { + this.init() + } } window.global = new Global() \ No newline at end of file