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

Nuxt 3 Support #49

Open
harlan-zw opened this issue Sep 11, 2023 · 1 comment
Open

Nuxt 3 Support #49

harlan-zw opened this issue Sep 11, 2023 · 1 comment

Comments

@harlan-zw
Copy link

Hey 👋 It looks like this module hasn't been updated for Nuxt 3. In an effort to improve the developer experience of modules, I've updated the module to clarify that it only supports Nuxt 2.

If Nuxt 3 support is added it will be moved to the https://github.com/nuxt-modules organisation.

Please let me know if you need any help :)

cc: @Geminii

@harlan-zw harlan-zw pinned this issue Sep 11, 2023
@simkuns
Copy link

simkuns commented Dec 7, 2023

Simple OneSignal implementation in Nuxt 3 example.

Screenshot 2023-12-07 at 02 27 12
npm install --save-dev @onesignal/onesignal-vue3
// nuxt.config.ts
export default defineNuxtConfig({
  plugins: [
    'onesignal.client'
  ],
  runtimeConfig: {
    public: {
      onesignalAppId: '<ONESIGNAL_APP_ID>',
    },
  },
});
// plugins/onesignal.client
import { useOneSignal } from '@onesignal/onesignal-vue3';

export default defineNuxtPlugin((nuxtApp) => {
  const appId = nuxtApp.$config.public.onesignalAppId;

  if (!appId) {
    return;
  }

  const OneSignal = useOneSignal();

  OneSignal.init({
    appId,
    allowLocalhostAsSecureOrigin: process.env.APP_ENV !== 'production',
  });

  return {
    provide: {
      OneSignal,
    },
  };
});

This component uses @nuxtjs/i18n, @sidebase/nuxt-auth and vuetify with auto-imports enabled.

<!-- components/OneSignalSubscribeButton.vue -->
<template>
  <ClientOnly>
    <v-tooltip location="bottom">
      <template #activator="{ props }">
        <v-btn
          variant="text"
          icon
          class="me-2"
          v-bind="props"
          @click.prevent="onClickBellButton"
        >
          <v-icon :color="bellOption.color" :icon="bellOption.icon" />
        </v-btn>
      </template>
      <span>{{ bellOption.tooltipText }}</span>
    </v-tooltip>
  </ClientOnly>
</template>

<script lang="ts" setup>
const BELL_STATE = {
  DISABLED: 'disabled',
  SUBSCRIBE: 'subscribe',
  SUBSCRIBED: 'subscribed',
} as const;

type BellState = (typeof BELL_STATE)[keyof typeof BELL_STATE];

defineOptions({
  name: 'OneSignalSubscribeButton',
});

const { $OneSignal } = useNuxtApp();
const i18n = useI18n();
const auth = useAuth();

const bellState = ref<BellState>(BELL_STATE.DISABLED);

const bellOption = computed(() => {
  switch (bellState.value) {
  case BELL_STATE.SUBSCRIBE:
    return {
      color: 'info',
      icon: 'mdi-bell',
      tooltipText: i18n.t('onesignal.attributes.bell.subscribe'),
    };
  case BELL_STATE.SUBSCRIBED:
    return {
      color: 'success',
      icon: 'mdi-bell-check',
      tooltipText: i18n.t('onesignal.attributes.bell.subscribed'),
    };
  case BELL_STATE.DISABLED:
  default:
    return {
      color: 'info',
      icon: 'mdi-bell-off',
      tooltipText: i18n.t('onesignal.attributes.bell.disabled'),
    };
  }
});

watch(auth.status, (status) => {
  if (status === 'authenticated') {
    $OneSignal.login(String(auth.data.value?.id));
  }
});

onBeforeMount(() => {
  updateBellState();

  $OneSignal.Notifications.addEventListener('permissionChange', onPermissionChange);
  $OneSignal.User.PushSubscription.addEventListener('change', onSubscriptionChange);
});

onBeforeUnmount(() => {
  $OneSignal.Notifications.removeEventListener('permissionChange', onPermissionChange);
  $OneSignal.User.PushSubscription.removeEventListener('change', onSubscriptionChange);
});

async function onClickBellButton() {
  switch (bellState.value) {
  case BELL_STATE.SUBSCRIBED:
    await $OneSignal.User.PushSubscription.optOut();
    break;
  case BELL_STATE.SUBSCRIBE:
    await $OneSignal.User.PushSubscription.optIn();
    break;
  case BELL_STATE.DISABLED:
    // $OneSignal.Slidedown.promptPush({ force: true });
    await $OneSignal.Notifications.requestPermission();
    break;
  }
}

function onSubscriptionChange() {
  updateBellState();
}

function onPermissionChange(isAllowed: boolean) {
  if (isAllowed) {
    $OneSignal.User.PushSubscription.optIn();
  }
}

function getSubscriptionState() {
  return {
    isPushNotificationsEnabled: $OneSignal.Notifications.permission,
    isOptedIn: $OneSignal.User.PushSubscription.optedIn,
  };
}

function updateBellState() {
  const state = getSubscriptionState();

  if (!state.isPushNotificationsEnabled) {
    bellState.value = BELL_STATE.DISABLED;

    return;
  }

  if (!state.isOptedIn) {
    bellState.value = BELL_STATE.SUBSCRIBE;

    return;
  }

  bellState.value = BELL_STATE.SUBSCRIBED;
}
</script>

Showing bell only to authenticated users.

<!-- example.vue -->
<template>
  <div>
    <LazyOneSignalSubscribeButton
      v-if="'$OneSignal' in $nuxt && $config.public.onesignalAppId && auth.status.value === 'authenticated'"
    />
  </div>
</template>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants