start the SMS notifications, beginning with the UI
This commit is contained in:
@@ -57,9 +57,12 @@ export const ACCOUNT_VIEW_CONSTANTS = {
|
||||
// Notification messages
|
||||
NOTIFICATIONS: {
|
||||
NEW_ACTIVITY_INFO: `
|
||||
This will only notify you when there is new relevant activity for you personally.
|
||||
Note that it runs on your device and many factors may affect delivery,
|
||||
so if you want a reliable but simple daily notification then choose a 'Reminder'.
|
||||
This will notify you with an app message when there is new relevant activity for you personally.
|
||||
Do you want more details?
|
||||
`,
|
||||
NEW_ACTIVITY_SMS_INFO: `
|
||||
This is opt-in: by turning it on you agree to receive text messages when there is new relevant activity for you personally.
|
||||
Standard message and data rates may apply, and you can turn it off at any time.
|
||||
Do you want more details?
|
||||
`,
|
||||
REMINDER_INFO: `
|
||||
|
||||
@@ -143,24 +143,48 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mt-4 mb-2">
|
||||
<!-- label -->
|
||||
<div>
|
||||
|
||||
<!--
|
||||
New Activity Notification: two delivery channels for the same alert.
|
||||
Both let the user pick a time; they differ only in how the alert is
|
||||
delivered (and therefore in the parameters passed to the notify-api):
|
||||
- In-App: on-device notification via the daily-notification-plugin.
|
||||
- SMS: text message sent by the notify-api (opt-in).
|
||||
-->
|
||||
<div class="mt-4 mb-1">
|
||||
<div class="font-semibold">
|
||||
New Activity Notification
|
||||
<button
|
||||
class="text-slate-400 fa-fw cursor-pointer"
|
||||
aria-label="Learn more about New Activity notifications"
|
||||
@click.stop="showNewActivityNotificationInfo"
|
||||
@click.stop="showNewActivityNotificationInfo(false)"
|
||||
>
|
||||
<font-awesome icon="question-circle" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<p class="text-xs text-slate-500">
|
||||
Get told about new relevant activity for you. Choose a delivery
|
||||
channel below -- you can turn on either one, or both.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Channel 1: In-App notification -->
|
||||
<div class="flex items-center justify-between mt-3 mb-2 pl-1">
|
||||
<!-- label -->
|
||||
<div>
|
||||
<font-awesome
|
||||
icon="comment"
|
||||
class="fa-fw text-slate-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
In-App Notification
|
||||
</div>
|
||||
<!-- toggle -->
|
||||
<div
|
||||
class="relative ml-2 cursor-pointer"
|
||||
role="switch"
|
||||
:aria-checked="notifyingNewActivity"
|
||||
aria-label="Toggle New Activity notifications"
|
||||
aria-label="Toggle New Activity notifications in app"
|
||||
tabindex="0"
|
||||
@click.stop.prevent="showNewActivityNotificationChoice()"
|
||||
>
|
||||
@@ -178,7 +202,7 @@
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="notifyingNewActivity" class="w-full">
|
||||
<div v-if="notifyingNewActivity" class="w-full pl-1">
|
||||
<div
|
||||
class="text-sm text-slate-500 mb-2 bg-white rounded px-3 py-2 border border-slate-200"
|
||||
>
|
||||
@@ -191,10 +215,75 @@
|
||||
class="w-full text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
|
||||
@click="editNewActivityNotification"
|
||||
>
|
||||
Edit New Activity Notification…
|
||||
Edit In-App Time…
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Channel 2: SMS text message (opt-in) -->
|
||||
<div class="flex items-center justify-between mt-3 mb-2 pl-1">
|
||||
<!-- label -->
|
||||
<div>
|
||||
<font-awesome
|
||||
icon="message"
|
||||
class="fa-fw text-slate-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
SMS Text Message
|
||||
<button
|
||||
class="text-slate-400 fa-fw cursor-pointer"
|
||||
aria-label="Learn more about New Activity SMS notifications"
|
||||
@click.stop="showNewActivityNotificationInfo(true)"
|
||||
>
|
||||
<font-awesome icon="question-circle" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- toggle -->
|
||||
<div
|
||||
class="relative ml-2 cursor-pointer"
|
||||
role="switch"
|
||||
:aria-checked="notifyingNewActivitySms"
|
||||
aria-label="Toggle New Activity notifications via SMS"
|
||||
tabindex="0"
|
||||
@click.stop.prevent="showNewActivitySmsNotificationChoice()"
|
||||
>
|
||||
<input
|
||||
:checked="notifyingNewActivitySms"
|
||||
type="checkbox"
|
||||
class="sr-only"
|
||||
readonly
|
||||
@click.stop.prevent
|
||||
@change.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>
|
||||
<div v-if="notifyingNewActivitySms" class="w-full pl-1">
|
||||
<div
|
||||
class="text-sm text-slate-500 mb-2 bg-white rounded px-3 py-2 border border-slate-200"
|
||||
>
|
||||
<div>
|
||||
<b>Time:</b>
|
||||
{{ notifyingNewActivitySmsTime.replace(" ", " ") }}
|
||||
</div>
|
||||
<div>
|
||||
<b>Text to:</b>
|
||||
<i>{{ notifyingNewActivitySmsPhone || "(number not set)" }}</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 text-center">
|
||||
<button
|
||||
class="w-full text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
|
||||
@click="editNewActivitySmsNotification"
|
||||
>
|
||||
Edit SMS Time…
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-2 text-center">
|
||||
<router-link class="text-sm text-blue-500" to="/help-notifications">
|
||||
Troubleshoot your notifications…
|
||||
@@ -546,7 +635,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Notification Push Server setting - only show on web platforms -->
|
||||
<div v-if="!isNativePlatform">
|
||||
<!-- This will be removed because we're no longer using PWA notifications. -->
|
||||
<div v-if="false">
|
||||
<h2 class="text-slate-500 text-sm font-bold mb-2">
|
||||
Notification Push Server
|
||||
</h2>
|
||||
@@ -931,6 +1021,12 @@ export default class AccountViewView extends Vue {
|
||||
// Notification properties
|
||||
notifyingNewActivity: boolean = false;
|
||||
notifyingNewActivityTime: string = "";
|
||||
// SMS delivery channel for New Activity (opt-in). MOCK-UP: state is currently
|
||||
// component-local. TODO: persist via settings + register the number and time
|
||||
// with the notify-api (SMS registration/verification flow).
|
||||
notifyingNewActivitySms: boolean = false;
|
||||
notifyingNewActivitySmsTime: string = "";
|
||||
notifyingNewActivitySmsPhone: string = "";
|
||||
notifyingReminder: boolean = false;
|
||||
notifyingReminderMessage: string = "";
|
||||
notifyingReminderTime: string = "";
|
||||
@@ -1216,9 +1312,11 @@ export default class AccountViewView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
async showNewActivityNotificationInfo(): Promise<void> {
|
||||
async showNewActivityNotificationInfo(isSms: boolean): Promise<void> {
|
||||
this.notify.confirm(
|
||||
ACCOUNT_VIEW_CONSTANTS.NOTIFICATIONS.NEW_ACTIVITY_INFO,
|
||||
isSms
|
||||
? ACCOUNT_VIEW_CONSTANTS.NOTIFICATIONS.NEW_ACTIVITY_SMS_INFO
|
||||
: ACCOUNT_VIEW_CONSTANTS.NOTIFICATIONS.NEW_ACTIVITY_INFO,
|
||||
async () => {
|
||||
await (this.$router as Router).push({
|
||||
name: "help-notification-types",
|
||||
@@ -1266,6 +1364,89 @@ export default class AccountViewView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the SMS delivery channel for New Activity notifications.
|
||||
*
|
||||
* MOCK-UP: reuses the time-picker dialog so the UI behaves like the in-app
|
||||
* channel, but the picked time is only held in component state for now.
|
||||
*
|
||||
* TODO (notify-api wiring): on enable, ensure the user has a verified phone
|
||||
* number, then POST the SMS-notification preference to the notify-api with
|
||||
* SMS-specific params (channel="sms", phoneNumber, sendTime) -- the same
|
||||
* alert as the in-app channel, delivered by a different transport. On
|
||||
* disable, tell the notify-api to remove the SMS preference.
|
||||
*/
|
||||
async showNewActivitySmsNotificationChoice(): Promise<void> {
|
||||
if (!this.notifyingNewActivitySms) {
|
||||
(
|
||||
this.$refs.pushNotificationPermission as PushNotificationPermission
|
||||
).open(
|
||||
DAILY_CHECK_TITLE,
|
||||
async (success: boolean, timeText: string) => {
|
||||
if (success) {
|
||||
// TODO: verify phone number + register SMS preference with notify-api
|
||||
this.notifyingNewActivitySms = true;
|
||||
this.notifyingNewActivitySmsTime = timeText;
|
||||
}
|
||||
},
|
||||
{ skipSchedule: true },
|
||||
);
|
||||
} else {
|
||||
// TODO: remove SMS preference from notify-api
|
||||
this.notifyingNewActivitySms = false;
|
||||
this.notifyingNewActivitySmsTime = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the time for the SMS delivery channel.
|
||||
*
|
||||
* MOCK-UP: updates component state only. TODO: PUT the updated sendTime to
|
||||
* the notify-api SMS preference.
|
||||
*/
|
||||
async editNewActivitySmsNotification(): Promise<void> {
|
||||
const dialog = this.$refs
|
||||
.pushNotificationPermission as PushNotificationPermission;
|
||||
|
||||
dialog.open(
|
||||
DAILY_CHECK_TITLE,
|
||||
async (success: boolean, timeText: string) => {
|
||||
if (!success) return;
|
||||
// TODO: PUT updated sendTime to notify-api SMS preference
|
||||
this.notifyingNewActivitySmsTime = timeText;
|
||||
this.notify.success(
|
||||
"New Activity SMS time updated.",
|
||||
TIMEOUTS.STANDARD,
|
||||
);
|
||||
},
|
||||
{ skipSchedule: true },
|
||||
);
|
||||
|
||||
// Pre-populate the dialog with the current SMS time
|
||||
setTimeout(() => {
|
||||
const timeMatch = this.notifyingNewActivitySmsTime.match(
|
||||
/(\d+):(\d+)\s*(AM|PM)/i,
|
||||
);
|
||||
if (timeMatch) {
|
||||
let hour = parseInt(timeMatch[1], 10);
|
||||
const minute = timeMatch[2];
|
||||
const isAm = timeMatch[3].toUpperCase() === "AM";
|
||||
if (hour === 12) {
|
||||
hour = 12;
|
||||
} else if (hour > 12) {
|
||||
hour = hour - 12;
|
||||
}
|
||||
const dialogComponent =
|
||||
dialog as unknown as PushNotificationPermissionRef;
|
||||
if (dialogComponent) {
|
||||
dialogComponent.hourInput = hour.toString();
|
||||
dialogComponent.minuteInput = minute;
|
||||
dialogComponent.hourAm = isAm;
|
||||
}
|
||||
}
|
||||
}, 150);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure native fetcher, sync starred plans, and schedule API-driven dual notification.
|
||||
*/
|
||||
|
||||
@@ -39,31 +39,32 @@
|
||||
something, so you can record thanks in here.
|
||||
</p>
|
||||
<p>
|
||||
This is a reliable message, but it doesn't contain any details about
|
||||
This is your own message activated in the app, but it doesn't contain any details about
|
||||
activity that might be especially interesting to you.
|
||||
Note that the timing is not precise: the device may deliver it a bit later than scheduled.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">New Activity Notifications</h2>
|
||||
<h2 class="text-xl font-semibold mt-4">New Activity Notifications -- In App</h2>
|
||||
<div>
|
||||
<p>
|
||||
The New Activity Notification will be sent to you when there is new, relevant activity
|
||||
The New Activity Notification will be activated in your app when there is new, relevant activity
|
||||
for you.
|
||||
It will only trigger if something involves you or a project of interest; it will not
|
||||
bug you for other, general activity.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mt-4">New Activity Notifications -- Texts From A Server</h2>
|
||||
<div>
|
||||
<p>
|
||||
This type is not as reliable as a Reminder Notification because mobile devices often
|
||||
suppress such notifications to save battery. (If you want to quickly check for relevant
|
||||
activity daily, use the Reminder Notification and open the app and look for a large green
|
||||
button that points out new activity that is personal to you. We are working on other
|
||||
ways to notify you more reliably.
|
||||
<router-link class="text-blue-500" to="/help">
|
||||
go here to follow us or contact us
|
||||
<font-awesome icon="chevron-right" class="fa-fw"></font-awesome>
|
||||
</router-link>.)
|
||||
This New Activity Notification SMS will be sent to you when there is new, relevant activity
|
||||
for you.
|
||||
It will only trigger if something involves you or a project of interest; it will not
|
||||
bug you for other, general activity.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- eslint-enable -->
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user