fixup! Add webpush front-end support

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-05-07 09:06:45 +02:00
parent 8e647724ae
commit bdae03fc52
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
6 changed files with 56 additions and 9 deletions

View File

@ -75,3 +75,34 @@ registerRoute(
],
})
);
self.addEventListener("push", async (event: any) => {
console.log("received push", event);
const options = {
body: "Ceci est une notification envoyée par Mobilizon !",
icon: "images/notification-flat.png",
vibrate: [100, 50, 100],
data: {
dateOfArrival: Date.now(),
primaryKey: 1,
},
actions: [
{
action: "explore",
title: "Go to the site",
icon: "images/checkmark.png",
},
{
action: "close",
title: "Close the notification",
icon: "images/xmark.png",
},
],
};
event.waitUntil(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
self.registration.showNotification("Push Notification", options)
);
});

View File

@ -18,11 +18,9 @@ function urlBase64ToUint8Array(base64String: string): Uint8Array {
}
export async function subscribeUserToPush(): Promise<PushSubscription | null> {
const registration = await navigator.serviceWorker.register(
"/service-worker.js"
);
const client = apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
const registration = await navigator.serviceWorker.ready;
const { data } = await client.mutate<{ config: IConfig }>({
mutation: WEB_PUSH,
});
@ -45,3 +43,8 @@ export async function subscribeUserToPush(): Promise<PushSubscription | null> {
}
return null;
}
export async function isSubscribed(): Promise<boolean> {
const registration = await navigator.serviceWorker.ready;
return (await registration.pushManager.getSubscription()) !== null;
}

View File

@ -18,6 +18,7 @@
<div class="setting-title">
<h2>{{ $t("Participation notifications") }}</h2>
</div>
<!-- <span v-if="isSubscribed()">{{ $t("You are already subscribed") }}</span> -->
<b-button
icon-left="rss"
@click="subscribeToWebPush"
@ -212,7 +213,10 @@ import { IUser } from "../../types/current-user.model";
import RouteName from "../../router/name";
import { IFeedToken } from "@/types/feedtoken.model";
import { CREATE_FEED_TOKEN, DELETE_FEED_TOKEN } from "@/graphql/feed_tokens";
import { subscribeUserToPush } from "../../services/push-subscription";
import {
isSubscribed,
subscribeUserToPush,
} from "../../services/push-subscription";
import { REGISTER_PUSH_MUTATION } from "@/graphql/webPush";
@Component({
@ -320,10 +324,11 @@ export default class Notifications extends Vue {
async subscribeToWebPush(): Promise<void> {
if (this.canShowWebPush()) {
const subscription = await subscribeUserToPush();
console.log("subscription", subscription?.toJSON());
const { data } = await this.$apollo.mutate({
mutation: REGISTER_PUSH_MUTATION,
variables: {
...subscription,
...subscription?.toJSON(),
},
});
console.log(data);
@ -336,6 +341,10 @@ export default class Notifications extends Vue {
return window.isSecureContext && !!navigator.serviceWorker;
}
async isSubscribed(): Promise<boolean> {
return await isSubscribed();
}
private async deleteFeedToken(token: string): Promise<void> {
await this.$apollo.mutate({
mutation: DELETE_FEED_TOKEN,

View File

@ -25,7 +25,7 @@ defmodule Mobilizon.GraphQL.Resolvers.PushSubscription do
def register_push_subscription(_parent, args, %{
context: %{current_user: %User{id: user_id}}
}) do
case Users.create_push_subscription(Map.put(args, :user_id, user_id)) do
case Users.create_push_subscription(%{data: args, user_id: user_id}) do
{:ok, %PushSubscription{}} ->
{:ok, "OK"}

View File

@ -3,6 +3,7 @@ defmodule Mobilizon.Users.PushSubscription do
alias Mobilizon.Users.User
import Ecto.Changeset
@primary_key {:id, :binary_id, autogenerate: true}
schema "user_push_subscriptions" do
field(:digest, :string)
belongs_to(:user, User)
@ -26,6 +27,7 @@ defmodule Mobilizon.Users.PushSubscription do
|> cast_embed(:data, with: &cast_data/2)
|> put_change(:digest, compute_digest(attrs.data))
|> validate_required([:digest, :user_id, :data])
|> unique_constraint([:digest, :user_id], name: :user_push_subscriptions_user_id_digest_index)
end
defp cast_data(schema, attrs) do
@ -42,6 +44,8 @@ defmodule Mobilizon.Users.PushSubscription do
end
defp compute_digest(data) do
data = Jason.encode!(data)
:sha256
|> :crypto.hash(data)
|> Base.encode16()

View File

@ -19,12 +19,12 @@ defmodule Mobilizon.Service.Notifier.Push do
@impl Notifier
def send(%User{id: user_id} = _user, %Activity{} = activity, _opts) do
%Page{elements: subscriptions} = Users.list_user_push_subscriptions(user_id, 1, 100)
Enum.each(subscriptions, &send_subscription(activity, &1))
Enum.map(subscriptions, &send_subscription(activity, &1.data))
end
@impl Notifier
def send(%User{} = user, activities, opts) when is_list(activities) do
Enum.each(activities, &Push.send(user, &1, opts))
Enum.map(activities, &Push.send(user, &1, opts))
end
defp payload(%Activity{subject: subject}) do