You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
566 lines
20 KiB
566 lines
20 KiB
<!--
|
|
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 />
|
|
|
|
<!-- CONTENT -->
|
|
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
|
<!-- Breadcrumb -->
|
|
<div class="mb-8">
|
|
<!-- Back -->
|
|
<div class="text-lg text-center font-light relative px-7">
|
|
<h1
|
|
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
|
@click="goBack()"
|
|
>
|
|
<font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
|
|
</h1>
|
|
</div>
|
|
|
|
<!-- Heading -->
|
|
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
|
Notification Help
|
|
</h1>
|
|
</div>
|
|
|
|
<!-- eslint-disable prettier/prettier -->
|
|
<div>
|
|
<p>Here are ways to test notifications and get them working.</p>
|
|
|
|
<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>
|
|
In Apple iOS, check "Settings" -> "Notifications", look for the Time
|
|
Safari app (or the browser you're using), and make sure notifications
|
|
are enabled.
|
|
</p>
|
|
<p>
|
|
In Android, hold on to the app icon, then 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
|
|
"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>
|
|
</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"
|
|
/>
|
|
</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 check that the browser tabs with Time Safari 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>
|
|
</div>
|
|
<!-- eslint-enable -->
|
|
</section>
|
|
</template>
|
|
<script lang="ts">
|
|
import { Component, Vue } from "vue-facing-decorator";
|
|
|
|
import QuickNav from "../components/QuickNav.vue";
|
|
import { NotificationIface } from "../constants/app";
|
|
import { DIRECT_PUSH_TITLE, sendTestThroughPushServer } from "../libs/util";
|
|
import PushNotificationPermission from "../components/PushNotificationPermission.vue";
|
|
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 { 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 },
|
|
mixins: [PlatformServiceMixin],
|
|
})
|
|
export default class HelpNotificationsView extends Vue {
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
|
$router!: Router;
|
|
subscriptionJSON?: PushSubscriptionJSON;
|
|
notifyingReminder = false;
|
|
notifyingReminderMessage = "";
|
|
notifyingReminderTime = "";
|
|
|
|
// Notification helper system
|
|
notify = createNotifyHelpers(this.$notify);
|
|
|
|
/**
|
|
* 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() {
|
|
try {
|
|
const registration = await navigator.serviceWorker?.ready;
|
|
const fullSub = await registration?.pushManager.getSubscription();
|
|
this.subscriptionJSON = fullSub?.toJSON();
|
|
} 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));
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 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.")
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
}
|
|
</script>
|
|
|