forked from jsnbuchanan/crowd-funder-for-time-pwa
update the notification-help to remove push-notification info, and other minor fixes
This commit is contained in:
@@ -143,29 +143,6 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Dev/test only: 10-minute rollover for rapid testing (Reminder Notifications) -->
|
||||
<label
|
||||
v-if="isNotProdServer"
|
||||
class="flex items-center justify-between cursor-pointer mt-3 py-2"
|
||||
@click="toggleReminderFastRollover"
|
||||
>
|
||||
<span class="text-sm text-slate-600">
|
||||
Use 10-minute rollover (testing)
|
||||
</span>
|
||||
<div class="relative ml-2">
|
||||
<input
|
||||
:checked="reminderFastRolloverForTesting"
|
||||
type="checkbox"
|
||||
class="sr-only"
|
||||
readonly
|
||||
@click.stop.prevent
|
||||
/>
|
||||
<div class="block bg-slate-500 w-14 h-8 rounded-full"></div>
|
||||
<div
|
||||
class="dot absolute left-1 top-1 bg-slate-400 w-6 h-6 rounded-full transition"
|
||||
></div>
|
||||
</div>
|
||||
</label>
|
||||
<div v-if="false" class="mt-4 flex items-center justify-between">
|
||||
<!-- label -->
|
||||
<div>
|
||||
|
||||
@@ -1,34 +1,3 @@
|
||||
<!--
|
||||
HelpNotificationsView.vue - Push Notification Help & Testing Component
|
||||
|
||||
User support component that provides comprehensive help and testing functionality
|
||||
for push notifications. Critical for users experiencing notification issues.
|
||||
|
||||
Key Features:
|
||||
- Push notification testing with multiple test scenarios
|
||||
- Comprehensive troubleshooting guide for notification issues
|
||||
- System permission checks for various platforms and browsers
|
||||
- Web push subscription management and diagnostics
|
||||
- Direct device testing without push server dependency
|
||||
|
||||
User Experience Impact:
|
||||
- High priority for users having notification issues
|
||||
- Primary troubleshooting resource for notification problems
|
||||
- Platform-specific guidance for iOS, Android, Mac, Windows
|
||||
- Technical diagnostic tools for developers and support
|
||||
|
||||
Database Operations:
|
||||
- Settings updates for notification preferences via PlatformServiceMixin
|
||||
- Simple key-value updates for notification configuration
|
||||
- No complex queries or data relationships
|
||||
|
||||
Security Considerations:
|
||||
- No sensitive data exposure in notifications or logs
|
||||
- Safe diagnostic information display
|
||||
- Secure push subscription handling
|
||||
|
||||
@author Matthew Raymer
|
||||
-->
|
||||
<template>
|
||||
<QuickNav />
|
||||
|
||||
@@ -57,576 +26,140 @@
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!-- eslint-disable prettier/prettier -->
|
||||
<div>
|
||||
<p>Here are ways to test notifications and get them working.</p>
|
||||
|
||||
<p class="mt-2 font-medium">Quick checklist:</p>
|
||||
<ul class="list-disc ml-4 mt-1">
|
||||
<li>
|
||||
Notifications are turned on for
|
||||
<strong>{{ AppString.APP_NAME_NO_SPACES }}</strong>
|
||||
(or the browser you use for the app) in system Settings.
|
||||
</li>
|
||||
<li>
|
||||
Battery and background settings are not restricting the app (see
|
||||
"Battery & background" under Check App Permissions).
|
||||
</li>
|
||||
<li>
|
||||
You're not in Focus or Do Not Disturb, or the app is allowed in that
|
||||
mode.
|
||||
</li>
|
||||
<li>Run the <strong>Full Test</strong> below.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Full Test</h2>
|
||||
<div>
|
||||
<p>
|
||||
If this works then you're all set.
|
||||
<button
|
||||
:class="primaryTestButtonClass"
|
||||
@click="sendTestWebPushMessage(true)"
|
||||
>
|
||||
Send Yourself a Test Web Push Message (Through Push Server but
|
||||
Skipping Client Filter)
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Android Users</h2>
|
||||
<div>
|
||||
<p>
|
||||
Note that you may not receive notifications when the app is in the
|
||||
background. When you're done working, close the app, and then you'll
|
||||
get the reminder notifications.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">
|
||||
If this app doesn't support notifications...
|
||||
<!-- Note that that exact verbiage shows in a message elsewhere. -->
|
||||
</h2>
|
||||
<div>
|
||||
<p>
|
||||
To be notified of interesting updates, install this app on your device
|
||||
(as opposed to using it inside the browser app). In Chrome, it may prompt
|
||||
you, and you can also look for the "Install" command in the browser
|
||||
settings.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">
|
||||
If you must enable notifications...
|
||||
<!-- Note that that exact verbiage shows in a message elsewhere. -->
|
||||
</h2>
|
||||
<div>
|
||||
<p>
|
||||
<button class="text-blue-500" @click="showNotificationChoice()">
|
||||
Click here.
|
||||
</button>
|
||||
<PushNotificationPermission ref="pushNotificationPermission" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">
|
||||
If you're waiting for system initialization...
|
||||
<!-- Note that that exact verbiage shows in a message elsewhere. -->
|
||||
</h2>
|
||||
<div>
|
||||
<p>
|
||||
... and it never stops, then there is a problem with the underlying
|
||||
service worker or push server mechanism in your browser. Your best bet
|
||||
is to follow the "Reinstall" steps below or use a different browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Check App Permissions</h2>
|
||||
<div>
|
||||
<p>
|
||||
If you use <strong>Focus</strong> (iOS) or <strong>Do Not
|
||||
Disturb</strong> (Android), notifications may be silenced. Check that
|
||||
{{ AppString.APP_NAME }} is allowed in that mode, or temporarily turn
|
||||
it off to test.
|
||||
</p>
|
||||
<p>
|
||||
In Apple iOS, check "Settings" -> "Notifications" and look for
|
||||
<strong>{{ AppString.APP_NAME_NO_SPACES }}</strong>
|
||||
(the app name in system Settings). If you added the app from a browser
|
||||
(e.g. "Add to Home Screen"), you may see
|
||||
the browser (e.g. Safari) instead — ensure notifications are enabled
|
||||
for that and for the site if listed separately. Make sure notifications
|
||||
are enabled.
|
||||
</p>
|
||||
<p>
|
||||
In Android, go to "Settings" -> "Notifications" and look for
|
||||
<strong>{{ AppString.APP_NAME_NO_SPACES }}</strong>
|
||||
(or Chrome if you installed from Chrome). Alternatively, long-press
|
||||
the app icon, select "App Info", then
|
||||
"Notifications" and make sure they're enabled. If it's still a problem
|
||||
then go further:
|
||||
</p>
|
||||
<p>
|
||||
If you installed the app with Chrome, make sure there are no other
|
||||
tabs with it open. Here are some ways to clear caches that can mess
|
||||
things up (and note that this clears out data from the installed app
|
||||
-- which is good to do while the app is installed):
|
||||
</p>
|
||||
<ul>
|
||||
<li class="list-disc ml-4">
|
||||
Go to Chrome "App Info", then "Storage & Cache" and "Clear Storage".
|
||||
</li>
|
||||
<li class="list-disc ml-4">
|
||||
Go to Chrome "Settings", then "Privacy and Security" and "Clear
|
||||
browsing data", then "Cookies and site data". Make sure the "Time
|
||||
Range" at the top shows "All time".
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
On a Mac, go to "Settings" and check "Notifications".
|
||||
<img
|
||||
src="../assets/help/mac-installed-app-settings.png"
|
||||
alt="Mac app settings"
|
||||
class="ml-4"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<h3 class="text-lg font-semibold mt-4">Battery & background</h3>
|
||||
<p>
|
||||
Notifications (especially scheduled reminders) can be blocked by
|
||||
battery or background settings. Check the following:
|
||||
</p>
|
||||
<ul class="list-disc ml-4">
|
||||
<li>
|
||||
<strong>iOS</strong>: In Settings → Battery, ensure Low Power Mode
|
||||
is off (it can delay background activity). In Settings → General →
|
||||
Background App Refresh, ensure it's on and that
|
||||
<strong>{{ AppString.APP_NAME_NO_SPACES }}</strong>
|
||||
(or Safari if you use the app from Safari) is allowed.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Android</strong>: In Settings → Apps →
|
||||
{{ AppString.APP_NAME_NO_SPACES }} (or Chrome if you use the PWA),
|
||||
open Battery and set to "Unrestricted" or "Don't
|
||||
optimize" so the app can run in the background. Battery Saver or
|
||||
Adaptive Battery can also limit notifications — try disabling them or
|
||||
adding an exception for the app.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Check Browser Permissions</h2>
|
||||
<div>
|
||||
<p>In Apple iOS, check Settings -> Notifications.</p>
|
||||
<p>In Android, check Settings -> Notifications.</p>
|
||||
|
||||
You can find more details about compatibility
|
||||
<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API#browser_compatibility"
|
||||
class="text-blue-500"
|
||||
target="_blank"
|
||||
>
|
||||
here <font-awesome icon="arrow-up-right-from-square" class="fa-fw" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">
|
||||
Check Operating System (OS) Permissions
|
||||
</h2>
|
||||
<div class="px-2">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">Mobile Phone - Apple iOS</h3>
|
||||
<div>
|
||||
Notifications require iOS 16.4 or higher. To check your iOS version,
|
||||
go to Settings > General > About > Software Version.
|
||||
</div>
|
||||
|
||||
<h3 class="text-lg font-semibold">Mobile Phone - Google Android</h3>
|
||||
<div>
|
||||
We recommend Chrome. It must be version 42 or higher. Check your
|
||||
version under Settings -> About Chrome.
|
||||
</div>
|
||||
|
||||
<h3 class="text-lg font-semibold">Desktop - Mac</h3>
|
||||
<div>
|
||||
<span>
|
||||
See "System Settings" -> "Notifications" and make sure it is
|
||||
enabled for the browser you're using. Note that these
|
||||
notifications require Mac OS 13; see your macOS version under
|
||||
Apple -> "About This Mac".
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h3 class="text-lg font-semibold">Desktop - Windows</h3>
|
||||
In Windows, check "Settings" -> "Notifications".
|
||||
<img
|
||||
src="../assets/help/windows-system-enable-notifications.png"
|
||||
alt="Windows system settings"
|
||||
class="ml-4"
|
||||
<label
|
||||
class="flex items-center justify-between cursor-pointer mt-3 py-2"
|
||||
@click="toggleReminderFastRollover"
|
||||
>
|
||||
<span class="text-sm text-slate-600">
|
||||
Use 10-minute rollover (testing)
|
||||
</span>
|
||||
<div class="relative ml-2">
|
||||
<input
|
||||
:checked="reminderFastRolloverForTesting"
|
||||
type="checkbox"
|
||||
class="sr-only"
|
||||
readonly
|
||||
@click.stop.prevent
|
||||
/>
|
||||
<div class="block bg-slate-500 w-14 h-8 rounded-full"></div>
|
||||
<div
|
||||
class="dot absolute left-1 top-1 bg-slate-400 w-6 h-6 rounded-full transition"
|
||||
></div>
|
||||
</div>
|
||||
<div>
|
||||
You can find more details about compatibility
|
||||
<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API#browser_compatibility"
|
||||
class="text-blue-500"
|
||||
target="_blank"
|
||||
>
|
||||
here <font-awesome icon="arrow-up-right-from-square" class="fa-fw" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Reinstall</h2>
|
||||
<div>
|
||||
<p>
|
||||
If all else fails, it's best to start over.
|
||||
</p>
|
||||
<p>
|
||||
Of course, you'll want to back up all your data first -- all seeds as
|
||||
well as the contacts & settings -- on the Profile
|
||||
<font-awesome icon="circle-user" /> page.
|
||||
</p>
|
||||
<p>
|
||||
Here are instructions to uninstall the app and clear out caches and
|
||||
storage. Note that you should first ensure that browser tabs with
|
||||
{{ AppString.APP_NAME }} are closed. (If any are open then that will
|
||||
interfere with your refresh.)
|
||||
</p>
|
||||
<ul class="ml-4 list-disc">
|
||||
<li>
|
||||
Clear cache.
|
||||
<ul>
|
||||
<li>
|
||||
In mobile, look for the browser app settings. This is true even
|
||||
for an installed app: go to the browser which you used to
|
||||
initially visit timesafari.app, because those settings affect
|
||||
the app. Look for "Delete browsing data" in the "Settings",
|
||||
under "Privacy and Security".
|
||||
</li>
|
||||
<li>
|
||||
In Chrome, go to `chrome://settings/cookies` and "all site data
|
||||
and permissions" for timesafari.app; in Firefox, go to
|
||||
`about:preferences` and search for "cache" then "Manage Data"
|
||||
for timesafari.app. Also manually remove the IndexedDB data if
|
||||
the DBs still show.)
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
Clear notification permission. (In Chrome, go to
|
||||
`chrome://settings/content/notifications`; in Firefox, go to
|
||||
`about:preferences` and search for "notifications".)
|
||||
</li>
|
||||
<li>
|
||||
Unregister service worker. (In Chrome, go to
|
||||
`chrome://serviceworker-internals/`; in Firefox, go to
|
||||
`about:serviceworkers`.)
|
||||
</li>
|
||||
<li>
|
||||
Clear "Cache Storage". (In Chrome, in dev tools under "Application";
|
||||
in Firefox, in dev tools under "Storage".)
|
||||
</li>
|
||||
</ul>
|
||||
<p>Then reinstall the app.</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">Tests</h2>
|
||||
<button
|
||||
:class="testButtonClass"
|
||||
@click="showTestNotification()"
|
||||
>
|
||||
Send Test Notification Directly to Device (Not Through Push Server)
|
||||
</button>
|
||||
<p>
|
||||
If that didn't show a notification on your device, the problem is that
|
||||
your browser or your operating system are not allowing notifications
|
||||
through. See "Check App Permissions" and "Check Browser Permissions" and
|
||||
"Check Operating System (OS) Permissions" above.
|
||||
</p>
|
||||
|
||||
<button
|
||||
:class="testButtonClass"
|
||||
@click="alertWebPushSubscription()"
|
||||
>
|
||||
Show Web Push Subscription Info
|
||||
</button>
|
||||
<p>
|
||||
If that showed "null" then the notification is not active.
|
||||
<button class="text-blue-500" @click="showNotificationChoice()">
|
||||
Click here.
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<button
|
||||
:class="testButtonClass"
|
||||
@click="sendTestWebPushMessage(true)"
|
||||
>
|
||||
Send Yourself a Test Web Push Message (Through Push Server but Skipping
|
||||
Client Filter)
|
||||
</button>
|
||||
<p>
|
||||
If that didn't show a notification on your device, there is a problem
|
||||
getting to the push server. Disable notifications and then enable them
|
||||
again.
|
||||
</p>
|
||||
|
||||
<button
|
||||
:class="testButtonClass"
|
||||
@click="sendTestWebPushMessage()"
|
||||
>
|
||||
Send Yourself a Test Web Push Message (Through Push Server and Client
|
||||
Filter)
|
||||
</button>
|
||||
<p>
|
||||
If you don't see a message, it could be that there is nothing new for
|
||||
you to see. If the previous test worked, then things should work fine.
|
||||
If you notice a full 24 hours where you get no notification and you know
|
||||
that there are new items that should show, gather as many details as
|
||||
possible and go to the bottom of
|
||||
<router-link to="help" class="text-blue-500"> this page </router-link>
|
||||
for ways to contact us.
|
||||
</p>
|
||||
</label>
|
||||
</div>
|
||||
<!-- eslint-enable -->
|
||||
</section>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
|
||||
import QuickNav from "../components/QuickNav.vue";
|
||||
import { AppString, NotificationIface } from "../constants/app";
|
||||
import { DIRECT_PUSH_TITLE, sendTestThroughPushServer } from "../libs/util";
|
||||
import PushNotificationPermission from "../components/PushNotificationPermission.vue";
|
||||
import { NotificationIface } from "../constants/app";
|
||||
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
|
||||
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
|
||||
import {
|
||||
NOTIFY_PUSH_NOT_SUBSCRIBED,
|
||||
NOTIFY_TEST_WEB_PUSH_SUCCESS,
|
||||
NOTIFY_TEST_WEB_PUSH_ERROR,
|
||||
NOTIFY_TEST_NOTIFICATION_SUCCESS,
|
||||
NOTIFY_TEST_NOTIFICATION_ERROR,
|
||||
} from "../constants/notifications";
|
||||
import { NotificationService } from "@/services/notifications";
|
||||
import { Router } from "vue-router";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
/**
|
||||
* HelpNotificationsView Component
|
||||
*
|
||||
* User support component that provides comprehensive help and testing functionality
|
||||
* for push notifications. Critical for users experiencing notification issues.
|
||||
*
|
||||
* Key features:
|
||||
* - Push notification testing with multiple test scenarios
|
||||
* - Comprehensive troubleshooting guide for notification issues
|
||||
* - System permission checks for various platforms and browsers
|
||||
* - Web push subscription management and diagnostics
|
||||
* - Direct device testing without push server dependency
|
||||
*
|
||||
* User Experience Impact:
|
||||
* - High priority for users having notification issues
|
||||
* - Primary troubleshooting resource for notification problems
|
||||
* - Platform-specific guidance for iOS, Android, Mac, Windows
|
||||
* - Technical diagnostic tools for developers and support
|
||||
*
|
||||
* Database Operations:
|
||||
* - Settings updates for notification preferences via PlatformServiceMixin
|
||||
* - Simple key-value updates for notification configuration
|
||||
* - No complex queries or data relationships
|
||||
*
|
||||
* Security Features:
|
||||
* - No sensitive data exposure in notifications or logs
|
||||
* - Safe diagnostic information display
|
||||
* - Secure push subscription handling
|
||||
* - Proper error handling without data leakage
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
@Component({
|
||||
components: { PushNotificationPermission, QuickNav },
|
||||
components: { QuickNav },
|
||||
mixins: [PlatformServiceMixin],
|
||||
})
|
||||
export default class HelpNotificationsView extends Vue {
|
||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||
$router!: Router;
|
||||
subscriptionJSON?: PushSubscriptionJSON;
|
||||
|
||||
apiServer: string = "";
|
||||
notifyingReminder = false;
|
||||
notifyingReminderMessage = "";
|
||||
notifyingReminderTime = "";
|
||||
reminderFastRolloverForTesting: boolean = false;
|
||||
|
||||
// Expose app name constants for template (Settings label vs product name)
|
||||
AppString = AppString;
|
||||
|
||||
// Notification helper system
|
||||
notify!: ReturnType<typeof createNotifyHelpers>;
|
||||
|
||||
/**
|
||||
* Computed property for consistent button styling
|
||||
* Used for all test buttons in the notification help interface
|
||||
*/
|
||||
get buttonClass(): string {
|
||||
return "block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md";
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed property for test button styling with margins
|
||||
* Used for test buttons in the Tests section
|
||||
*/
|
||||
get testButtonClass(): string {
|
||||
return this.buttonClass + " mt-4 mb-2";
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed property for primary test button styling
|
||||
* Used for the main test button with bottom margin
|
||||
*/
|
||||
get primaryTestButtonClass(): string {
|
||||
return this.buttonClass + " mb-2";
|
||||
}
|
||||
|
||||
/**
|
||||
* Vue mounted lifecycle hook
|
||||
*
|
||||
* Initializes the component by setting up push subscription information.
|
||||
* Retrieves the current push subscription from the service worker and stores
|
||||
* it for display and testing purposes.
|
||||
*
|
||||
* Handles errors gracefully with proper logging without exposing sensitive data.
|
||||
*/
|
||||
async mounted() {
|
||||
// Initialize notification helpers
|
||||
this.notify = createNotifyHelpers(this.$notify);
|
||||
|
||||
try {
|
||||
const registration = await navigator.serviceWorker?.ready;
|
||||
const fullSub = await registration?.pushManager.getSubscription();
|
||||
this.subscriptionJSON = fullSub?.toJSON();
|
||||
const settings = await this.$settings();
|
||||
this.apiServer = settings.apiServer || "";
|
||||
this.notifyingReminder = !!settings.notifyingReminderTime;
|
||||
this.notifyingReminderMessage = settings.notifyingReminderMessage || "";
|
||||
this.notifyingReminderTime = settings.notifyingReminderTime || "";
|
||||
this.reminderFastRolloverForTesting =
|
||||
!!settings.reminderFastRolloverForTesting;
|
||||
} catch (error) {
|
||||
logger.error("Mount error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates back to the previous page
|
||||
* Provides consistent navigation behavior for the back button
|
||||
*/
|
||||
goBack(): void {
|
||||
this.$router.back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays web push subscription information
|
||||
*
|
||||
* Shows the current push subscription details to the user for diagnostic purposes.
|
||||
* Useful for troubleshooting push notification issues and verifying subscription status.
|
||||
*/
|
||||
alertWebPushSubscription() {
|
||||
alert(JSON.stringify(this.subscriptionJSON));
|
||||
}
|
||||
async toggleReminderFastRollover(): Promise<void> {
|
||||
const next = !this.reminderFastRolloverForTesting;
|
||||
await this.$saveSettings({
|
||||
reminderFastRolloverForTesting: next,
|
||||
});
|
||||
this.reminderFastRolloverForTesting = next;
|
||||
|
||||
/**
|
||||
* Sends test web push message through push server
|
||||
*
|
||||
* Sends a test notification through the push server to verify the complete
|
||||
* notification pipeline. Can skip client-side filtering for testing purposes.
|
||||
*
|
||||
* @param skipFilter - Whether to skip client-side message filtering
|
||||
*/
|
||||
async sendTestWebPushMessage(skipFilter: boolean = false) {
|
||||
if (!this.subscriptionJSON) {
|
||||
this.notify.error(NOTIFY_PUSH_NOT_SUBSCRIBED.message, TIMEOUTS.STANDARD);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await sendTestThroughPushServer(this.subscriptionJSON, skipFilter);
|
||||
|
||||
this.notify.success(
|
||||
this.getTestWebPushSuccessMessage(skipFilter),
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error("Got an error sending test notification:", error);
|
||||
this.notify.error(NOTIFY_TEST_WEB_PUSH_ERROR.message, TIMEOUTS.STANDARD);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows test notification directly to device
|
||||
*
|
||||
* Displays a test notification directly through the service worker without
|
||||
* using the push server. Useful for testing local notification capabilities.
|
||||
*/
|
||||
showTestNotification() {
|
||||
const TEST_NOTIFICATION_TITLE = "It Worked";
|
||||
navigator.serviceWorker?.ready
|
||||
.then((registration) => {
|
||||
return registration.showNotification(TEST_NOTIFICATION_TITLE, {
|
||||
body: "This is your test notification.",
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
this.notify.success(
|
||||
this.getTestNotificationSuccessMessage(TEST_NOTIFICATION_TITLE),
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error("Got a notification error:", error);
|
||||
this.notify.error(
|
||||
NOTIFY_TEST_NOTIFICATION_ERROR.message,
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows notification permission choice dialog
|
||||
*
|
||||
* Opens the notification permission dialog to allow users to enable
|
||||
* notifications. Updates notification settings upon successful permission grant.
|
||||
*/
|
||||
showNotificationChoice() {
|
||||
(this.$refs.pushNotificationPermission as PushNotificationPermission).open(
|
||||
DIRECT_PUSH_TITLE,
|
||||
async (success: boolean, timeText: string, message?: string) => {
|
||||
if (success) {
|
||||
await this.$updateSettings({
|
||||
notifyingReminderMessage: message,
|
||||
notifyingReminderTime: timeText,
|
||||
});
|
||||
this.notifyingReminder = true;
|
||||
this.notifyingReminderMessage = message || "";
|
||||
this.notifyingReminderTime = timeText;
|
||||
if (this.notifyingReminder) {
|
||||
try {
|
||||
const service = NotificationService.getInstance();
|
||||
if (Capacitor.getPlatform() !== "android") {
|
||||
await service.cancelDailyNotification();
|
||||
}
|
||||
},
|
||||
);
|
||||
const time24h = this.parseTimeTo24Hour(this.notifyingReminderTime);
|
||||
const title = "Daily Reminder";
|
||||
const body =
|
||||
this.notifyingReminderMessage ||
|
||||
"Click to share some gratitude with the world -- even if they're unnamed.";
|
||||
await service.scheduleDailyNotification({
|
||||
time: time24h,
|
||||
title,
|
||||
body,
|
||||
priority: "normal",
|
||||
...(next ? { rolloverIntervalMinutes: 10 } : {}),
|
||||
});
|
||||
this.notify.success(
|
||||
next
|
||||
? "Reminder will repeat every 10 minutes (testing)."
|
||||
: "Reminder will repeat daily (24h).",
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
"[HelpNotificationsView] Reschedule after fast-rollover toggle failed:",
|
||||
err,
|
||||
);
|
||||
this.notify.error(
|
||||
"Failed to update reminder interval. Please try again.",
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates test web push success message
|
||||
*
|
||||
* Creates a dynamic success message based on whether client filtering is skipped.
|
||||
*
|
||||
* @param skipFilter - Whether client-side message filtering was skipped
|
||||
* @returns Formatted success message string
|
||||
*/
|
||||
private getTestWebPushSuccessMessage(skipFilter: boolean): string {
|
||||
return (
|
||||
NOTIFY_TEST_WEB_PUSH_SUCCESS.message +
|
||||
(skipFilter ? "." : " if there are new items in your feed.")
|
||||
);
|
||||
}
|
||||
private parseTimeTo24Hour(timeStr: string): string {
|
||||
const timeMatch = timeStr.match(/(\d+):(\d+)\s*(AM|PM)/i);
|
||||
if (!timeMatch) {
|
||||
return "09:00";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates test notification success message
|
||||
*
|
||||
* Creates a dynamic success message with the notification title inserted.
|
||||
*
|
||||
* @param title - The title of the test notification
|
||||
* @returns Formatted success message string
|
||||
*/
|
||||
private getTestNotificationSuccessMessage(title: string): string {
|
||||
return NOTIFY_TEST_NOTIFICATION_SUCCESS.message.replace("{title}", title);
|
||||
let hour = parseInt(timeMatch[1], 10);
|
||||
const minute = timeMatch[2];
|
||||
const isAm = timeMatch[3].toUpperCase() === "AM";
|
||||
|
||||
if (isAm && hour === 12) {
|
||||
hour = 0;
|
||||
} else if (!isAm && hour !== 12) {
|
||||
hour = hour + 12;
|
||||
}
|
||||
|
||||
return `${hour.toString().padStart(2, "0")}:${minute}`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,20 +4,7 @@ This directory contains the automated end-to-end test suite for Time Safari usin
|
||||
|
||||
## Test Structure
|
||||
|
||||
Tests are organized by feature area and numbered for execution order:
|
||||
|
||||
- `00-noid-tests.spec.ts` - Tests for unregistered users
|
||||
- `05-invite.spec.ts` - Contact invitation functionality
|
||||
- `10-check-usage-limits.spec.ts` - Usage limit verification
|
||||
- `20-create-project.spec.ts` - Project creation
|
||||
- `25-create-project-x10.spec.ts` - Bulk project creation
|
||||
- `30-record-gift.spec.ts` - Gift recording
|
||||
- `33-record-gift-x10.spec.ts` - Bulk gift recording
|
||||
- `35-record-gift-from-image-share.spec.ts` - Gift recording from shared images
|
||||
- `37-record-gift-on-project.spec.ts` - Project-specific gift recording
|
||||
- `40-add-contact.spec.ts` - Contact management
|
||||
- `50-record-offer.spec.ts` - Offer recording
|
||||
- `60-new-activity.spec.ts` - Activity feed updates
|
||||
Tests are organized by feature area and numbered for execution order.
|
||||
|
||||
## Key Files
|
||||
|
||||
|
||||
@@ -138,12 +138,12 @@ await page.waitForFunction(() => {
|
||||
3. If you find yourself wanting to see the testing process try something like this:
|
||||
|
||||
```
|
||||
npx playwright test -c playwright.config-local.ts test-playwright/60-new-activity.spec.ts --grep "New offers for another user" --headed
|
||||
npx playwright test -c playwright.config-local.ts test-playwright/40-add-contact.spec.ts --grep "New offers for another user" --headed
|
||||
```
|
||||
|
||||
This command allows you to:
|
||||
|
||||
- **Run a specific test file**: `test-playwright/60-new-activity.spec.ts`
|
||||
- **Run a specific test file**: `test-playwright/40-add-contact.spec.ts`
|
||||
- **Filter to a specific test**: `--grep "New offers for another user"` runs only tests with that name
|
||||
- **See the browser**: `--headed` opens the browser window so you can watch the test execute
|
||||
- **Use local config**: `-c playwright.config-local.ts` uses the local configuration file
|
||||
|
||||
Reference in New Issue
Block a user