Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for creating push messages #636

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/routes/console/project-[project]/messaging/create.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,26 @@
);
break;
case ProviderTypes.Push:
const customData: Record<string, string> = {};
const { data } = $messageParams[ProviderTypes.Push];
if (data && data.length > 0) {
data.forEach((item) => {
if (item[0] === '') return;
customData[item[0]] = item[1];
});
}

response = await sdk.forProject.client.call(
'POST',
new URL(
sdk.forProject.client.config.endpoint + '/messaging/providers/telesign'
),
new URL(sdk.forProject.client.config.endpoint + '/messaging/messages/push'),
{
'X-Appwrite-Project': sdk.forProject.client.config.project,
'content-type': 'application/json',
'X-Appwrite-Mode': 'admin'
},
{
...$messageParams[$providerType],
data: customData,
messageId
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { message } from './store';
import { ProviderTypes } from '../providerType.svelte';
import SMSPreview from './smsPreview.svelte';
import PushPreview from './pushPreview.svelte';
</script>

<Container>
Expand All @@ -14,6 +15,8 @@
<EmailPreview />
{:else if $message.providerType === ProviderTypes.Sms}
<SMSPreview />
{:else if $message.providerType === ProviderTypes.Push}
<PushPreview />
{/if}
<Delete />
</Container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
import { CardGrid, Heading } from '$lib/components';
import { FormList, InputText, InputTextarea } from '$lib/elements/forms';
import { message } from './store';
import PushPhone from '../pushPhone.svelte';
</script>

<CardGrid>
<div class="grid-1-2-col-1 u-flex-vertical u-cross-start u-gap-16">
<Heading tag="h6" size="7">Preview</Heading>
<PushPhone title={$message.data.title} body={$message.data.body} />
</div>
<svelte:fragment slot="aside">
<FormList>
<InputText id="title" label="Title" disabled={true} bind:value={$message.data.title}>
</InputText>
<InputTextarea
id="message"
label="Message"
disabled={true}
bind:value={$message.data.body}>
</InputTextarea>
</FormList>
</svelte:fragment>

<svelte:fragment slot="actions">
<!-- TODO: Add support for editing draft messages -->
<!-- <Button disabled={$message.status !== 'draft'} on:click={() => console.log('click')}
>Edit message</Button> -->
</svelte:fragment>
</CardGrid>
16 changes: 16 additions & 0 deletions src/routes/console/project-[project]/messaging/pushPhone.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
export let title = '';
export let body = '';
</script>

<!-- TODO: Style to look like a push notification -->
<div class="phone card is-only-desktop">
<p class="body-text-1 u-bold">{title}</p>
<p class="body-text-2">{body}</p>
</div>

<style lang="scss">
.phone {
inline-size: calc(320 * 1rem / 16);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
<script context="module" lang="ts">
export async function createPushMessage(params: PushMessageParams) {
const response = await sdk.forProject.client.call(
'POST',
new URL(sdk.forProject.client.config.endpoint + '/messaging/messages/push'),
{
'X-Appwrite-Project': sdk.forProject.client.config.project,
'content-type': 'application/json',
'X-Appwrite-Mode': 'admin'
},
params
);

return response.json();
}

export function validateData(data: string[][]) {
if (!data || data.length === 0) return;

if (data.length === 1 && data[0][0] === '' && data[0][1] === '') return;

const dataKeys = new Set<string>();
for (let i = 0; i < data.length; i++) {
if (data[i][0] === '') {
return 'Keys cannot be empty';
}
if (data[i][1] === '') {
return 'Values cannot be empty';
}
dataKeys.add(data[i][0]);
}

if (dataKeys.size !== data.length) {
return 'Keys must be unique';
}

return '';
}
</script>

<script lang="ts">
import { messageParams, providerType, MessageStatuses, type PushMessageParams } from './store';
import {
Button,
FormItem,
FormItemPart,
FormList,
Helper,
InputEmail,
InputRadio,
InputText,
InputTextarea,
Label
} from '$lib/elements/forms';
import { Pill } from '$lib/elements';
import { CustomId, Modal } from '$lib/components';
import { user } from '$lib/stores/user';
import { clickOnEnter } from '$lib/helpers/a11y';
import { ID } from '@appwrite.io/console';
import { sdk } from '$lib/stores/sdk';
import { ProviderTypes } from '../providerType.svelte';
import PushPhone from '../pushPhone.svelte';
import { onMount } from 'svelte';

let showCustomId = false;
let showTest = false;
let selected = 'self';
let otherEmail = '';
let dataError = '';
let customData: [string, string][] = [];

onMount(() => {
$messageParams[ProviderTypes.Push].data = customData || [['', '']];
});

async function sendTestMessage() {
const email = selected === 'self' ? $user.email : otherEmail;
console.log(email);

createPushMessage({
topics: $messageParams[ProviderTypes.Push]?.topics || [],
targets: $messageParams[ProviderTypes.Push]?.targets || [],
description: $messageParams[ProviderTypes.Push]?.description || 'Test push',
status: MessageStatuses.PROCESSING,
messageId: ID.unique(),
// TODO: properly handle the test email address
users: ['steven'],
body: $messageParams[ProviderTypes.Push]?.body || '',
title: $messageParams[ProviderTypes.Push]?.title || '',
data: $messageParams[ProviderTypes.Push]?.data || []
});
}

$: otherEmail = selected === 'self' ? '' : otherEmail;
$: customData = $messageParams[ProviderTypes.Push].data;
$: dataError = validateData(customData || []);
</script>

<div class="u-flex u-gap-24">
<FormList class="u-stretch">
<InputText
id="title"
label="Title"
placeholder="Enter title"
bind:value={$messageParams[ProviderTypes.Push]['title']}>
</InputText>
<div class="u-colum-gap-2">
<InputTextarea
id="message"
label="Message"
placeholder="Type here..."
bind:value={$messageParams[ProviderTypes.Push]['body']}>
</InputTextarea>
<!-- TODO: Add support for draft messages -->
<!-- <div class="u-flex u-main-end">
<Button text on:click={() => (showTest = true)}>Send test message</Button>
</div> -->
<Modal
title="Send test message"
bind:show={showTest}
onSubmit={sendTestMessage}
size="big">
<slot />
<InputRadio
label={$user.phone}
bind:group={selected}
value="self"
id="self"
name="selected" />
<InputRadio
label="Other"
bind:group={selected}
value="other"
id="other"
name="selected"
fullWidth>
<svelte:fragment slot="description">
Enter the phone number to which the test message will be
<div
on:click={() => (selected = 'other')}
on:keyup|self={clickOnEnter}
role="button"
tabindex="0">
<InputEmail
showLabel={false}
id="email"
label="Email"
placeholder="Enter email"
bind:value={otherEmail} />
</div>
</svelte:fragment>
</InputRadio>

<svelte:fragment slot="footer">
<Button secondary on:click={() => (showTest = false)}>Cancel</Button>
<Button submit>Send</Button>
</svelte:fragment>
</Modal>
</div>
<form class="form">
<Label>Custom data <span class="u-color-text-gray">(Optional)</span></Label>
<div class=" u-grid u-gap-8">
<ul class="form-list" style="--p-form-list-gap: 1rem">
{#each customData || [] as _, rowIndex}
<FormItem isMultiple>
<InputText
id={`${rowIndex}-key`}
isMultiple
fullWidth
bind:value={$messageParams[ProviderTypes.Push].data[rowIndex][0]}
placeholder="Enter key"
label="Key"
showLabel={false} />

<InputText
id={`${rowIndex}-value`}
isMultiple
fullWidth
bind:value={$messageParams[ProviderTypes.Push].data[rowIndex][1]}
placeholder="Enter value"
label="Value"
showLabel={false}
required />
<FormItemPart alignEnd>
<Button
text
on:click={() => {
if (customData.length === 1) {
$messageParams[ProviderTypes.Push].data = [['', '']];
return;
}

$messageParams[ProviderTypes.Push].data = customData.filter(
(_, i) => i !== rowIndex
);
}}>
<span class="icon-x" aria-hidden="true" />
</Button>
</FormItemPart>
</FormItem>
{/each}
</ul>
{#if dataError}
<Helper type="warning">{dataError}</Helper>
{/if}
<Button
noMargin
text
disabled={customData && customData[customData.length - 1][0] === ''}
on:click={() => {
$messageParams[ProviderTypes.Push].data = [...customData, ['', '']];
}}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Add data</span>
</Button>
</div>
</form>
<InputText
id="description"
label="Description"
placeholder="Enter description"
tooltip="Provide a summary of the message. Users won't see this description."
bind:value={$messageParams[$providerType]['description']}>
</InputText>
{#if !showCustomId}
<div>
<Pill button on:click={() => (showCustomId = !showCustomId)}
><span class="icon-pencil" aria-hidden="true" /><span class="text">
Message ID
</span></Pill>
</div>
{:else}
<CustomId
bind:show={showCustomId}
name="Message"
bind:id={$messageParams[$providerType].messageId}
autofocus={false} />
{/if}
</FormList>
<PushPhone
title={$messageParams[$providerType]['title']}
body={$messageParams[$providerType]['body']} />
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
import { ProviderTypes } from '../providerType.svelte';
import EmailFormList from './emailFormList.svelte';
import SmsFormList from './smsFormList.svelte';
import PushFormList, { validateData } from './pushFormList.svelte';

async function beforeSubmit() {
}
async function beforeSubmit() {}
</script>

<WizardStep {beforeSubmit}>
<WizardStep
{beforeSubmit}
nextDisabled={$providerType === ProviderTypes.Push &&
!!validateData($messageParams[ProviderTypes.Push].data)}>
<svelte:fragment slot="title">Message</svelte:fragment>
<svelte:fragment slot="subtitle">
<!-- TODO: update documentation link -->
Expand All @@ -21,5 +24,7 @@
<EmailFormList />
{:else if $providerType === ProviderTypes.Sms}
<SmsFormList />
{:else if $providerType === ProviderTypes.Push}
<PushFormList />
{/if}
</WizardStep>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type SMSMessageParams = MessageParams & {
export type PushMessageParams = MessageParams & {
title: string;
body: string;
data: Record<string, string>;
data: [string, string][];
action?: string;
icon?: string;
sound?: string;
Expand Down