mirror of
https://github.com/andrei0x309/yup-live-chrome-extension.git
synced 2025-01-19 04:50:43 +00:00
chore: changes for 1.0.9
This commit is contained in:
parent
cbf3e7b900
commit
b7300bc684
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,3 +24,4 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
releases
|
||||
src/client/inject.js
|
||||
|
10
CHANGELOG.MD
10
CHANGELOG.MD
@ -1,5 +1,13 @@
|
||||
# Change Log
|
||||
|
||||
## [Version 1.0.9]
|
||||
|
||||
- added: browser notifications(work similar to push notifications) for comment, mention, follow with the ability to open the notification in app
|
||||
- changed login to use app.yup.io
|
||||
- removed external navigation to yup-live
|
||||
- added more settings
|
||||
- fixed some service worker issues
|
||||
|
||||
## [Version 1.0.8]
|
||||
|
||||
- migrated from windicss to tailwindcss
|
||||
@ -13,7 +21,7 @@
|
||||
|
||||
## [Version 1.0.6]
|
||||
|
||||
- refactored notifications
|
||||
- refactored notifications
|
||||
- added support for aggregated notifications
|
||||
- added support for follow notification
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "yup live",
|
||||
"description": "Light alternative extension for yup protocol",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.9",
|
||||
"manifest_version": 3,
|
||||
"icons": {
|
||||
"16": "src/assets/icons/yup_ext_16.png",
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { SEND_AUTH_NOTIF, ENABLE_RIGHT_CLICK, DISABLE_RIGHT_CLICK } from '@/constants/messeges';
|
||||
import { initStorage } from '@/utils/storage'
|
||||
import { getStore, setProfile, setNotifStorageNotifs, setSettings, setNotifStorageLastRewardNotif, getNotifStorageLastRewardNotif } from '@/utils/storage'
|
||||
import { getStore, setProfile, setNotifStorageNotifs, setSettings,
|
||||
setNotifStorageLastRewardNotif, getNotifStorageLastRewardNotif, getSetting, setSetting } from '@/utils/storage'
|
||||
import type { Notification } from '@/utils/types';
|
||||
import { API_BASE } from '@/constants/config';
|
||||
import { getNotifications } from '@/utils/notifications';
|
||||
import { setBadge } from '@/utils/chrome-misc'
|
||||
import { setBadge, extrenalNavigate } from '@/utils/chrome-misc'
|
||||
import { closeTo } from '@/utils/time';
|
||||
import { getActionUsage } from '@/utils/user';
|
||||
import { executeVote, getVotePayload } from '@/utils/votes';
|
||||
@ -14,6 +15,27 @@ const yupExtensionId = 'nhmeoaahigiljjdkoagafdccikgojjoi'
|
||||
|
||||
console.info('Service worker started')
|
||||
|
||||
let notificationUrl: string
|
||||
|
||||
const buttons = {
|
||||
buttons: [{
|
||||
title: 'Open in App',
|
||||
}]
|
||||
}
|
||||
|
||||
const notificationActionListner = async (id: string) => {
|
||||
try {
|
||||
const url = new URL(notificationUrl ?? 'https://app.yup.io/notifications')
|
||||
extrenalNavigate(url.href)
|
||||
chrome.notifications.clear(id)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (!chrome.notifications.onButtonClicked.hasListener(notificationActionListner)){
|
||||
chrome.notifications.onButtonClicked.addListener(notificationActionListner)
|
||||
}
|
||||
|
||||
const onRightClickLike = async (store, info, tab) => {
|
||||
const vote = await executeVote(getVotePayload({
|
||||
@ -74,7 +96,7 @@ const alarmHandler = async () => {
|
||||
type: null,
|
||||
limit: '15',
|
||||
skip: '0',
|
||||
userId: store.user.auth.userId
|
||||
address: store.user.auth.address
|
||||
})
|
||||
}
|
||||
requests.coinGecko = fetch('https://api.coingecko.com/api/v3/simple/price?ids=yup&vs_currencies=usd')
|
||||
@ -114,8 +136,8 @@ const alarmHandler = async () => {
|
||||
}
|
||||
setSettings(updateSettings).catch(console.error)
|
||||
|
||||
if (store.settings?.chromeNotifWhenReward && notSeen.some(notif => notif.action === 'reward')) {
|
||||
const rewardNotif = notSeen.find(notif => notif.action === 'reward')
|
||||
if (store.settings?.chromeNotifWhenReward && notSeen.some(notif => notif.eventType === 'reward')) {
|
||||
const rewardNotif = notSeen.find(notif => notif.eventType === 'reward')
|
||||
if (rewardNotif) {
|
||||
const storeReward = (await getNotifStorageLastRewardNotif())
|
||||
|
||||
@ -128,13 +150,57 @@ const alarmHandler = async () => {
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||
title: 'Yup Live Extension',
|
||||
message: `You have been alocated a future reward of ${rewardNotif.quantity} YUP`,
|
||||
message: `You have been alocated a future reward of ${rewardNotif?.meta.quantity ?? "unknown"} YUP`,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (store.settings?.enableFollowNotif && notSeen.some(notif => notif.eventType === 'follow')) {
|
||||
const followNotif = notSeen.filter(notif => notif.eventType === 'follow').sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0]
|
||||
const lastFollowNotif = await getSetting('lastfollowNotif') as number
|
||||
const isNew = !lastFollowNotif || ( !closeTo(new Date(lastFollowNotif), new Date(followNotif.createdAt), 2e4))
|
||||
if (followNotif && isNew) {
|
||||
notificationUrl = followNotif?.senders?.[0]._id ? `${API_BASE}/account/${followNotif?.senders?.[0]._id}`: undefined
|
||||
await chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||
title: 'Yup Live Extension',
|
||||
message: `${followNotif.senders[0].handle} has followed you`,
|
||||
...(buttons)
|
||||
})
|
||||
await setSetting('lastfollowNotif', new Date(followNotif.createdAt).getTime())
|
||||
}
|
||||
} else if (store.settings?.enableCommentNotif && notSeen.some(notif => notif.eventType === 'comment')) {
|
||||
const commentNotif = notSeen.filter(notif => notif.eventType === 'comment').sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0]
|
||||
const lastCommentNotif = await getSetting('lastCommentNotif') as number
|
||||
const isNew = !lastCommentNotif || ( !closeTo(new Date(lastCommentNotif), new Date(commentNotif.createdAt), 2e4))
|
||||
if (commentNotif && isNew) {
|
||||
notificationUrl = commentNotif?.meta?.postid ? `${API_BASE}/post/${commentNotif?.meta?.postid}`: undefined
|
||||
await chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||
title: 'Yup Live Extension',
|
||||
message: `${commentNotif.senders[0].handle} has commented on your post`,
|
||||
...(buttons)
|
||||
})
|
||||
await setSetting('lastCommentNotif', new Date(commentNotif.createdAt).getTime())
|
||||
}
|
||||
} else if (store.settings?.enableMentionNotif && notSeen.some(notif => notif.eventType === 'mention')) {
|
||||
const mentionNotif = notSeen.filter(notif => notif.eventType === 'mention').sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0]
|
||||
const lastMentionNotif = await getSetting('lastMentionNotif') as number
|
||||
const isNew = !lastMentionNotif || ( !closeTo(new Date(lastMentionNotif), new Date(mentionNotif.createdAt), 2e4))
|
||||
if (mentionNotif && isNew) {
|
||||
notificationUrl = mentionNotif?.meta?.postid ? `${API_BASE}/post/${mentionNotif?.meta?.postid}`: undefined
|
||||
await chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||
title: 'Yup Live Extension',
|
||||
message: `${mentionNotif.senders[0].handle} has mentioned you`,
|
||||
...(buttons)
|
||||
})
|
||||
await setSetting('lastMentionNotif', new Date(mentionNotif.createdAt).getTime())
|
||||
}
|
||||
}
|
||||
|
||||
if (store.settings?.chromeNotifWhenAbleToVote) {
|
||||
await getActionUsage(store?.user?.auth?.userId)
|
||||
}
|
||||
@ -187,13 +253,16 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
||||
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
|
||||
try {
|
||||
console.log('Message received', request)
|
||||
if (request.type === SEND_AUTH_NOTIF) {
|
||||
const lastLoginNotifTime = Number(await getSetting('lastLoginNotif'))
|
||||
const moreThanOneDay = (new Date().getTime() - lastLoginNotifTime) > 864e5
|
||||
if (request.type === SEND_AUTH_NOTIF && moreThanOneDay) {
|
||||
chrome.notifications.create({
|
||||
type: 'basic',
|
||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||
title: 'Yup Live Extension',
|
||||
message: 'You have been logged in.',
|
||||
})
|
||||
setSetting('lastLoginNotif', new Date().getTime())
|
||||
sendResponse({ success: true })
|
||||
} else if (request.type === ENABLE_RIGHT_CLICK) {
|
||||
await enableRightClickVote()
|
||||
|
@ -1,42 +0,0 @@
|
||||
var SEND_VOTE = 'SEND_VOTE';
|
||||
var SET_AUTH = 'SET_AUTH';
|
||||
var WebCommunicator = /** @class */ (function () {
|
||||
function WebCommunicator(injectAuthMethod) {
|
||||
if (injectAuthMethod === void 0) { injectAuthMethod = false; }
|
||||
var _this = this;
|
||||
this._send = function (data) {
|
||||
window.postMessage(data, "*");
|
||||
};
|
||||
this.submitVote = function (vote) {
|
||||
return _this._send({
|
||||
type: SEND_VOTE,
|
||||
payload: vote
|
||||
});
|
||||
};
|
||||
this.setAuth = function (authData) {
|
||||
return _this._send({
|
||||
type: SET_AUTH,
|
||||
payload: authData
|
||||
});
|
||||
};
|
||||
if (injectAuthMethod) {
|
||||
;
|
||||
window.yupSetAuth = this.setAuth;
|
||||
}
|
||||
else {
|
||||
;
|
||||
window.yupSetAuth = function () { return Promise.resolve(null); };
|
||||
}
|
||||
;
|
||||
window.yupSubmitVote = this.submitVote;
|
||||
}
|
||||
return WebCommunicator;
|
||||
}());
|
||||
var allowRegex = /^((http:|https:))?([/][/])?(www.)?[a-zA-Z\-_0-9]{0,}\.?[a-zA-Z\-_0-9]{0,}(yup.info.gf|yup-live.pages.dev|.yup.io|yup-team.vercel.app|localhost\/|localhost:)(.*)/gm;
|
||||
var isAllowed = allowRegex.test(window.location.href);
|
||||
if (isAllowed) {
|
||||
new WebCommunicator(true);
|
||||
}
|
||||
else {
|
||||
new WebCommunicator();
|
||||
}
|
@ -35,6 +35,8 @@ class WebCommunicator {
|
||||
const allowRegex = /^((http:|https:))?([/][/])?(www.)?[a-zA-Z\-_0-9]{0,}\.?[a-zA-Z\-_0-9]{0,}(yup.info.gf|yup-live.pages.dev|.yup.io|yup-team.vercel.app|localhost\/|localhost:)(.*)/gm
|
||||
const isAllowed = allowRegex.test(window.location.href)
|
||||
|
||||
console.log('isAllowed', isAllowed)
|
||||
|
||||
if(isAllowed) {
|
||||
new WebCommunicator(true)
|
||||
} else {
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
let loader;
|
||||
|
||||
const appBase = "https://app.yup.io";
|
||||
|
||||
export let notif: Notification;
|
||||
</script>
|
||||
|
||||
@ -33,7 +35,7 @@
|
||||
</p>
|
||||
<p class="text-xs text-gray-200 my-0 mt-1">
|
||||
<span
|
||||
on:click={() => extrenalNavigate(`https://yup-live.pages.dev/post/${notif.meta.postid}`)}
|
||||
on:click={() => extrenalNavigate(`${appBase}/post/${notif.meta.postid}`)}
|
||||
aria-hidden
|
||||
class="text-blue-200 interactive-svg">{finalUrl}</span
|
||||
>
|
||||
@ -105,7 +107,7 @@
|
||||
<p
|
||||
aria-hidden
|
||||
class="text-xs text-gray-200 my-0 mt-1"
|
||||
on:click={() => extrenalNavigate(`https://yup-live.pages.dev/web3-profile/${sender?._id}`)}
|
||||
on:click={() => extrenalNavigate(`${appBase}/account/${sender?._id}`)}
|
||||
>
|
||||
<b>{sender?.handle || `${sender?._id?.slice(0, 6)}...`}</b>
|
||||
followed you.
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const API_BASE = 'https://api.yup.io'
|
||||
export const DEV_BASE = 'http://localhost:4566'
|
||||
export const YUP_LIVE_BASE = 'https://yup-live.pages.dev'
|
||||
export const YUP_LIVE_BASE = 'https://app.yup.io'
|
||||
export const APP_BASE = YUP_LIVE_BASE
|
@ -11,14 +11,10 @@
|
||||
</svg>
|
||||
</a>
|
||||
<div class="text-[1.6rem] mb-4 uppercase">
|
||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/login`)}">
|
||||
Login
|
||||
</a>
|
||||
/
|
||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/sign-up`)}" >
|
||||
Signup
|
||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/auth`)}">
|
||||
Login on web app
|
||||
</a>
|
||||
</div>
|
||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/login`)}">
|
||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/auth`)}">
|
||||
<svg enable-background="new 0 0 48 48" viewBox="0 0 48 48" class="w-14 svg-fill my-4"><path d="M0.115,30.348c0-7.771,6.303-14.073,14.074-14.073h0.002h14.071V8.051l19.622,15.261l-19.622,15.26v-8.225 H10.458c-3.887,0-7.037,3.152-7.037,7.037c0,0.906,0.186,1.768,0.5,2.564C1.566,37.434,0.115,34.064,0.115,30.348z"/></svg>
|
||||
</a>
|
||||
|
@ -36,12 +36,12 @@
|
||||
|
||||
<div class="h-24 leading-6 main-section">
|
||||
<div class="flex my-2">
|
||||
<div on:click={() => extrenalNavigate(`${APP_BASE}/score/${$mainStore.user.auth.address}`)} aria-hidden class="flex flex-col w-16 mt-1 px-2 py-3 mr-4 link">
|
||||
<div aria-hidden class="flex flex-col w-16 mt-1 px-2 py-3 mr-3 link">
|
||||
<span class="text-[0.6rem] mb-1">Score</span><span class="text-[0.95rem] mb-1"
|
||||
>{$mainStore?.user?.profile?.yupScore?.toFixed(0)}</span
|
||||
><span class="text-[0.7rem]">100<br />MAX</span>
|
||||
</div>
|
||||
<div on:click={() => extrenalNavigate(`${APP_BASE}/profile/${$mainStore.user.auth.userId}`)} aria-hidden class="flex flex-col justify-center mb-1 w-16">
|
||||
<div on:click={() => extrenalNavigate(`${APP_BASE}/account/${$mainStore.user.auth.userId}`)} aria-hidden class="flex flex-col justify-center mb-1 w-16">
|
||||
<ImgLoader source={avatar} bind:this={loader}>
|
||||
<img
|
||||
style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1);' : '' }"
|
||||
@ -82,7 +82,7 @@
|
||||
<span class="text-[0.6rem] mt-4 -ml-1">{handle.length >= 12 ? handle.slice(0, 10) + "..." : handle}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div on:click={() => extrenalNavigate(`${APP_BASE}/raw-influence/${$mainStore.user.auth.userId}`)} aria-hidden class="flex flex-col w-16 mt-1 ml-4 px-2 py-3 link">
|
||||
<div aria-hidden class="flex flex-col w-16 mt-1 ml-3 px-2 py-3 link">
|
||||
<span class="text-[0.6rem] mb-1">Influence</span><span class="text-[0.95rem] mb-1"
|
||||
>{$mainStore?.user?.profile?.yup?.weight}</span
|
||||
><span class="text-[0.7rem]">10<br />MAX</span>
|
||||
|
@ -68,7 +68,7 @@ const changeNotifsType = async (t : string[] | null) => {
|
||||
{:else}
|
||||
<div class="text-[0.75rem] py-1">
|
||||
<span on:click={() => changeNotifsType(null)} aria-hidden class="inline-block mr-2 interactive-svg text-blue-200 interactive-svg" >All</span>
|
||||
<span on:click={() => changeNotifsType(['reward'])} aria-hidden class="text-blue-200 interactive-svg interactive-svg text-blue-200 interactive-svg">Rewards</span>
|
||||
<span on:click={() => changeNotifsType(['reward'])} aria-hidden class="text-blue-200 interactive-svg interactive-svg interactive-svg">Rewards</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
{#each notifs as notif}
|
||||
|
@ -138,6 +138,36 @@ onMount(async () => {
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="switch switch--4 text-[0.8rem] flex flex-col mb-4">
|
||||
<span class="inline-block">Browser notification on follow</span>
|
||||
<label class="switch__label mt-2">
|
||||
<input on:click={() => setSettingsLocal('enableFollowNotif')} type="checkbox" class="switch__input"
|
||||
checked={settings.enableFollowNotif}
|
||||
>
|
||||
<span class="switch__design"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="switch switch--4 text-[0.8rem] flex flex-col mb-4">
|
||||
<span class="inline-block">Browser notification on mention</span>
|
||||
<label class="switch__label mt-2">
|
||||
<input on:click={() => setSettingsLocal('enableMentionNotif')} type="checkbox" class="switch__input"
|
||||
checked={settings.enableMentionNotif}
|
||||
>
|
||||
<span class="switch__design"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="switch switch--4 text-[0.8rem] flex flex-col mb-4">
|
||||
<span class="inline-block">Browser notification on comment</span>
|
||||
<label class="switch__label mt-2">
|
||||
<input on:click={() => setSettingsLocal('enableCommentNotif')} type="checkbox" class="switch__input"
|
||||
checked={settings.enableCommentNotif}
|
||||
>
|
||||
<span class="switch__design"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
{:else}
|
||||
|
@ -49,6 +49,13 @@ export const storageDefault = {
|
||||
refilNotifTimestamp: 0,
|
||||
enableRightClick: false,
|
||||
enableRightClickNotif: false,
|
||||
lastLoginNotif: 0,
|
||||
enableCommentNotif: false,
|
||||
enableMentionNotif: false,
|
||||
enableFollowNotif: false,
|
||||
lastfollowNotif: 0,
|
||||
lastCommentNotif: 0,
|
||||
lastMentionNotif: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,3 +155,14 @@ export const getSettings = async () => {
|
||||
return store ? store.store.settings as StorageType['settings'] : storageDefault.settings as StorageType['settings']
|
||||
}
|
||||
|
||||
export const getSetting = async (setting: keyof StorageType['settings']) => {
|
||||
const settings = await getSettings()
|
||||
return settings[setting]
|
||||
}
|
||||
|
||||
export const setSetting = async <K extends keyof StorageType['settings']>(setting: K, value: StorageType['settings'][K]) => {
|
||||
const settings = await getSettings()
|
||||
settings[setting] = value
|
||||
await setSettings(settings)
|
||||
}
|
||||
|
||||
|
@ -33,4 +33,5 @@ export interface Vote {
|
||||
avatar: string
|
||||
}[]
|
||||
message?: string
|
||||
seen: boolean
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user