Compare commits
8 Commits
cbf3e7b900
...
047a87fde1
Author | SHA1 | Date |
---|---|---|
Andrei O | 047a87fde1 | |
Andrei O | d46722811f | |
Andrei O | 076e18d475 | |
Andrei O | b1122d2cdf | |
Andrei O | 999573a9e5 | |
Andrei O | d9b45313a9 | |
Andrei O | 50abf0f647 | |
Andrei O | b7300bc684 |
|
@ -24,3 +24,4 @@ dist-ssr
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
releases
|
releases
|
||||||
|
src/client/inject.js
|
||||||
|
|
26
CHANGELOG.MD
26
CHANGELOG.MD
|
@ -1,5 +1,29 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## [Version 1.1.3]
|
||||||
|
|
||||||
|
- minor fix to prevent console error log on fetch failure
|
||||||
|
|
||||||
|
## [Version 1.1.2]
|
||||||
|
|
||||||
|
- changed service worker open notification to use app.yup.io
|
||||||
|
- fixed follow notification with multiple senders
|
||||||
|
|
||||||
|
## [Version 1.1.1]
|
||||||
|
|
||||||
|
- changed auth condition
|
||||||
|
- refactor image loader for notification images
|
||||||
|
- added constant for yup app base url
|
||||||
|
- other cleanups
|
||||||
|
|
||||||
|
## [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]
|
## [Version 1.0.8]
|
||||||
|
|
||||||
- migrated from windicss to tailwindcss
|
- migrated from windicss to tailwindcss
|
||||||
|
@ -13,7 +37,7 @@
|
||||||
|
|
||||||
## [Version 1.0.6]
|
## [Version 1.0.6]
|
||||||
|
|
||||||
- refactored notifications
|
- refactored notifications
|
||||||
- added support for aggregated notifications
|
- added support for aggregated notifications
|
||||||
- added support for follow notification
|
- added support for follow notification
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "yup live",
|
"name": "yup live",
|
||||||
"description": "Light alternative extension for yup protocol",
|
"description": "Light extension helper for yup social platform.",
|
||||||
"version": "1.0.8",
|
"version": "1.1.3",
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "src/assets/icons/yup_ext_16.png",
|
"16": "src/assets/icons/yup_ext_16.png",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "yup-live-browser-extension",
|
"name": "yup-live-browser-extension",
|
||||||
"description": "Yup Live Browser Extension",
|
"description": "Yup Live Browser Extension",
|
||||||
"version": "1.0.8",
|
"version": "1.1.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"author": "andrei0x309",
|
"author": "andrei0x309",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
@ -1,19 +1,42 @@
|
||||||
import { SEND_AUTH_NOTIF, ENABLE_RIGHT_CLICK, DISABLE_RIGHT_CLICK } from '@/constants/messeges';
|
import { SEND_AUTH_NOTIF, ENABLE_RIGHT_CLICK, DISABLE_RIGHT_CLICK } from '@/constants/messeges';
|
||||||
import { initStorage } from '@/utils/storage'
|
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 type { Notification } from '@/utils/types';
|
||||||
import { API_BASE } from '@/constants/config';
|
import { API_BASE } from '@/constants/config';
|
||||||
import { getNotifications } from '@/utils/notifications';
|
import { getNotifications } from '@/utils/notifications';
|
||||||
import { setBadge } from '@/utils/chrome-misc'
|
import { setBadge, extrenalNavigate } from '@/utils/chrome-misc'
|
||||||
import { closeTo } from '@/utils/time';
|
import { closeTo } from '@/utils/time';
|
||||||
import { getActionUsage } from '@/utils/user';
|
import { getActionUsage } from '@/utils/user';
|
||||||
import { executeVote, getVotePayload } from '@/utils/votes';
|
import { executeVote, getVotePayload } from '@/utils/votes';
|
||||||
|
import { YUP_APP_BASE } from '@/constants/config';
|
||||||
|
|
||||||
// Disable conflict with yup extension
|
// Disable conflict with yup extension
|
||||||
const yupExtensionId = 'nhmeoaahigiljjdkoagafdccikgojjoi'
|
const yupExtensionId = 'nhmeoaahigiljjdkoagafdccikgojjoi'
|
||||||
|
|
||||||
console.info('Service worker started')
|
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 ?? `${YUP_APP_BASE}/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 onRightClickLike = async (store, info, tab) => {
|
||||||
const vote = await executeVote(getVotePayload({
|
const vote = await executeVote(getVotePayload({
|
||||||
|
@ -74,10 +97,11 @@ const alarmHandler = async () => {
|
||||||
type: null,
|
type: null,
|
||||||
limit: '15',
|
limit: '15',
|
||||||
skip: '0',
|
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')
|
requests.coinGecko = fetch('https://api.coingecko.com/api/v3/simple/price?ids=yup&vs_currencies=usd')
|
||||||
|
requests.coinGecko.catch(console.warn)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const profile = await requests.profile as Response
|
const profile = await requests.profile as Response
|
||||||
|
@ -102,7 +126,7 @@ const alarmHandler = async () => {
|
||||||
if (store?.settings.notificationsEnabled) {
|
if (store?.settings.notificationsEnabled) {
|
||||||
try {
|
try {
|
||||||
const notifications = await requests.notifications as Notification[]
|
const notifications = await requests.notifications as Notification[]
|
||||||
const notSeen = notifications.reverse().filter(notif => !notif.seen)
|
const notSeen = notifications.filter(notif => !notif.seen)
|
||||||
const updateSettings = {} as Record<string, boolean>
|
const updateSettings = {} as Record<string, boolean>
|
||||||
if (notSeen.length > 0) {
|
if (notSeen.length > 0) {
|
||||||
setBadge(String(notSeen.length))
|
setBadge(String(notSeen.length))
|
||||||
|
@ -114,8 +138,8 @@ const alarmHandler = async () => {
|
||||||
}
|
}
|
||||||
setSettings(updateSettings).catch(console.error)
|
setSettings(updateSettings).catch(console.error)
|
||||||
|
|
||||||
if (store.settings?.chromeNotifWhenReward && notSeen.some(notif => notif.action === 'reward')) {
|
if (store.settings?.chromeNotifWhenReward && notSeen.some(notif => notif.eventType === 'reward')) {
|
||||||
const rewardNotif = notSeen.find(notif => notif.action === 'reward')
|
const rewardNotif = notSeen.find(notif => notif.eventType === 'reward')
|
||||||
if (rewardNotif) {
|
if (rewardNotif) {
|
||||||
const storeReward = (await getNotifStorageLastRewardNotif())
|
const storeReward = (await getNotifStorageLastRewardNotif())
|
||||||
|
|
||||||
|
@ -128,13 +152,57 @@ const alarmHandler = async () => {
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||||
title: 'Yup Live Extension',
|
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 ? `${YUP_APP_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 ? `${YUP_APP_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 ? `${YUP_APP_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) {
|
if (store.settings?.chromeNotifWhenAbleToVote) {
|
||||||
await getActionUsage(store?.user?.auth?.userId)
|
await getActionUsage(store?.user?.auth?.userId)
|
||||||
}
|
}
|
||||||
|
@ -151,7 +219,7 @@ const alarmHandler = async () => {
|
||||||
chrome.alarms.create(
|
chrome.alarms.create(
|
||||||
'alarm',
|
'alarm',
|
||||||
{
|
{
|
||||||
periodInMinutes: 1,
|
periodInMinutes: 0.1,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -186,14 +254,17 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => {
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
|
||||||
try {
|
try {
|
||||||
console.log('Message received', request)
|
// 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({
|
chrome.notifications.create({
|
||||||
type: 'basic',
|
type: 'basic',
|
||||||
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
iconUrl: chrome.runtime.getURL('src/assets/icons/yup_ext_128.png'),
|
||||||
title: 'Yup Live Extension',
|
title: 'Yup Live Extension',
|
||||||
message: 'You have been logged in.',
|
message: 'You have been logged in.',
|
||||||
})
|
})
|
||||||
|
setSetting('lastLoginNotif', new Date().getTime())
|
||||||
sendResponse({ success: true })
|
sendResponse({ success: true })
|
||||||
} else if (request.type === ENABLE_RIGHT_CLICK) {
|
} else if (request.type === ENABLE_RIGHT_CLICK) {
|
||||||
await enableRightClickVote()
|
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();
|
|
||||||
}
|
|
|
@ -3,9 +3,8 @@
|
||||||
|
|
||||||
export let source
|
export let source
|
||||||
|
|
||||||
let loading = true
|
let loading = true
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let error = false
|
|
||||||
|
|
||||||
export const onLoad = () => {
|
export const onLoad = () => {
|
||||||
loading = false
|
loading = false
|
||||||
|
@ -14,18 +13,14 @@
|
||||||
|
|
||||||
export const onError = () => {
|
export const onError = () => {
|
||||||
loading = false
|
loading = false
|
||||||
error = true
|
source = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if(isUrlInvalid(source)) {
|
if(isUrlInvalid(source)) {
|
||||||
loading = false
|
source = undefined
|
||||||
error = true
|
|
||||||
} else {
|
} else {
|
||||||
loading = true
|
|
||||||
error = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -34,7 +29,7 @@
|
||||||
{#if loading || loaded}
|
{#if loading || loaded}
|
||||||
<slot name="img">
|
<slot name="img">
|
||||||
</slot>
|
</slot>
|
||||||
{:else if error}
|
{:else if source === undefined}
|
||||||
<slot name="error">
|
<slot name="error">
|
||||||
</slot>
|
</slot>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
import { chromeUrl } from "@/utils/chrome-misc";
|
import { chromeUrl } from "@/utils/chrome-misc";
|
||||||
import { extrenalNavigate } from "@/utils/chrome-misc";
|
import { extrenalNavigate } from "@/utils/chrome-misc";
|
||||||
import LikeIcon from '@/components/LikeIcon.svelte';
|
import LikeIcon from '@/components/LikeIcon.svelte';
|
||||||
|
import { YUP_APP_BASE } from "@/constants/config";
|
||||||
|
|
||||||
let loader;
|
|
||||||
|
|
||||||
export let notif: Notification;
|
export let notif: Notification;
|
||||||
|
const numImages = notif?.senders?.length ?? 0;
|
||||||
|
let loaders: ImgLoader[] = Array(numImages).fill(null);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if notif.eventType === "vote"}
|
{#if notif.eventType === "vote"}
|
||||||
|
@ -33,7 +36,7 @@
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-gray-200 my-0 mt-1">
|
<p class="text-xs text-gray-200 my-0 mt-1">
|
||||||
<span
|
<span
|
||||||
on:click={() => extrenalNavigate(`https://yup-live.pages.dev/post/${notif.meta.postid}`)}
|
on:click={() => extrenalNavigate(`${YUP_APP_BASE}/post/${notif.meta.postid}`)}
|
||||||
aria-hidden
|
aria-hidden
|
||||||
class="text-blue-200 interactive-svg">{finalUrl}</span
|
class="text-blue-200 interactive-svg">{finalUrl}</span
|
||||||
>
|
>
|
||||||
|
@ -69,13 +72,13 @@
|
||||||
</div>
|
</div>
|
||||||
{:else if ["follow"].includes(notif.eventType)}
|
{:else if ["follow"].includes(notif.eventType)}
|
||||||
<div class="flex flex-col notifBody">
|
<div class="flex flex-col notifBody">
|
||||||
{#each notif.senders as sender}
|
{#each notif.senders as sender, i}
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<ImgLoader bind:this={loader} source="{sender?.avatar} ">
|
<ImgLoader bind:this={loaders[i]} source="{sender?.avatar}" >
|
||||||
<img
|
<img
|
||||||
class="notificationImage"
|
class="notificationImage"
|
||||||
on:load={() => loader.onLoad()}
|
on:load={() => loaders[i]?.onLoad()}
|
||||||
on:error={() => loader.onError()}
|
on:error={() => loaders[i]?.onError()}
|
||||||
style={$mainStore.settings.theme === "light" ? "filter: invert(0.9);" : ""}
|
style={$mainStore.settings.theme === "light" ? "filter: invert(0.9);" : ""}
|
||||||
slot="img"
|
slot="img"
|
||||||
src={sender.avatar}
|
src={sender.avatar}
|
||||||
|
@ -105,7 +108,7 @@
|
||||||
<p
|
<p
|
||||||
aria-hidden
|
aria-hidden
|
||||||
class="text-xs text-gray-200 my-0 mt-1"
|
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(`${YUP_APP_BASE}/account/${sender?._id}`)}
|
||||||
>
|
>
|
||||||
<b>{sender?.handle || `${sender?._id?.slice(0, 6)}...`}</b>
|
<b>{sender?.handle || `${sender?._id?.slice(0, 6)}...`}</b>
|
||||||
followed you.
|
followed you.
|
||||||
|
@ -149,6 +152,8 @@
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
margin-top: 0.5rem;
|
margin-top: 0.5rem;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.233);
|
||||||
|
background-image: linear-gradient(rgba(0, 0, 0, 0.123), rgba(0, 0, 0, 0.123));
|
||||||
}
|
}
|
||||||
|
|
||||||
.notifBody {
|
.notifBody {
|
||||||
|
|
|
@ -40,7 +40,9 @@ $: {
|
||||||
<div class="flex items-center flex-col text-[0.8rem] leading-4 mb-4">
|
<div class="flex items-center flex-col text-[0.8rem] leading-4 mb-4">
|
||||||
<div class="mb relative">
|
<div class="mb relative">
|
||||||
<ImgLoader source={tab?.favIconUrl ?? ''} bind:this={loader}>
|
<ImgLoader source={tab?.favIconUrl ?? ''} bind:this={loader}>
|
||||||
<img style="{ $mainStore.settings.theme === 'light'? 'filter: invert(0.9);' : '' }" slot="img" on:load={() => loader.onLoad()} on:error={() => loader.onError}
|
<img style="{ $mainStore.settings.theme === 'light'? 'filter: invert(0.9);' : '' }" slot="img"
|
||||||
|
on:load={() => loader.onLoad()}
|
||||||
|
on:error={() => loader.onError}
|
||||||
class="w-5 h-5 mt-2 rounded-full wicon" src="{tab?.favIconUrl ?? ''}" alt="favicon" />
|
class="w-5 h-5 mt-2 rounded-full wicon" src="{tab?.favIconUrl ?? ''}" alt="favicon" />
|
||||||
<svg class="w-5 h-5 mt-2 rounded-full wicon" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(0.9);' : '' }" slot="error" viewBox="0 0 512 512"><g><polygon points="40,38.999 40,468.998 215,293.998 270,348.998 360,258.998 470,358.998 470,38.999 " style="fill:#EFF3F6;"/>
|
<svg class="w-5 h-5 mt-2 rounded-full wicon" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(0.9);' : '' }" slot="error" viewBox="0 0 512 512"><g><polygon points="40,38.999 40,468.998 215,293.998 270,348.998 360,258.998 470,358.998 470,38.999 " style="fill:#EFF3F6;"/>
|
||||||
<g><circle cx="150" cy="158.999" r="40" style="fill:#FCD884;"/></g><g><polygon points="470,358.998 470,468.998 385,468.998 385,463.998 270,348.998 360,258.998 " style="fill:#70993F;"/></g><g><polygon points="385,463.998 385,468.998 40,468.998 215,293.998 270,348.998" style="fill:#80AF52;"/></g></g><g/></svg>
|
<g><circle cx="150" cy="158.999" r="40" style="fill:#FCD884;"/></g><g><polygon points="470,358.998 470,468.998 385,468.998 385,463.998 270,348.998 360,258.998 " style="fill:#70993F;"/></g><g><polygon points="385,463.998 385,468.998 40,468.998 215,293.998 270,348.998" style="fill:#80AF52;"/></g></g><g/></svg>
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
export const API_BASE = 'https://api.yup.io'
|
export const API_BASE = 'https://api.yup.io'
|
||||||
export const DEV_BASE = 'http://localhost:4566'
|
export const YUP_APP_BASE = 'https://app.yup.io'
|
||||||
export const YUP_LIVE_BASE = 'https://yup-live.pages.dev'
|
|
||||||
export const APP_BASE = YUP_LIVE_BASE
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { navigate } from '@/utils/router'
|
import { navigate } from '@/utils/router'
|
||||||
import { mainStore } from '@/utils/store'
|
import { mainStore } from '@/utils/store'
|
||||||
// https://yup-live.pages.dev
|
// https://yup-live.pages.dev
|
||||||
import { APP_BASE } from '@/constants/config'
|
import { YUP_APP_BASE } from '@/constants/config'
|
||||||
import Alert from '@/components/Alert.svelte'
|
import Alert from '@/components/Alert.svelte'
|
||||||
import { alertStore } from '@/utils/store'
|
import { alertStore } from '@/utils/store'
|
||||||
import PageLoader from "@/components/PageLoader.svelte";
|
import PageLoader from "@/components/PageLoader.svelte";
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
store = await getStore()
|
store = await getStore()
|
||||||
alertStore.set(alert)
|
alertStore.set(alert)
|
||||||
auth = store?.user?.auth?.userId ?? false
|
auth = store?.user?.auth?.authToken ?? false
|
||||||
if(auth){
|
if(auth){
|
||||||
await mainStore.set(store)
|
await mainStore.set(store)
|
||||||
await navigate('/')
|
await navigate('/')
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<div class="entry" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1);' : '' }">
|
<div class="entry" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1);' : '' }">
|
||||||
|
|
||||||
<a href="#app" on:click="{() => extrenalNavigate(APP_BASE)}">
|
<a href="#app" on:click="{() => extrenalNavigate(YUP_APP_BASE)}">
|
||||||
<h1 aria-label="logo" class="logo inline-flex items-center text-[1.6rem] font-bold gap-2.5 pl-8">
|
<h1 aria-label="logo" class="logo inline-flex items-center text-[1.6rem] font-bold gap-2.5 pl-8">
|
||||||
<span class="gradient-text" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1.1);' : '' }" >YUP</span>
|
<span class="gradient-text" style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1.1);' : '' }" >YUP</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import PageLoader from '@/components/PageLoader.svelte';
|
import PageLoader from '@/components/PageLoader.svelte';
|
||||||
import { getExtensionVersion, extrenalNavigate } from '@/utils/chrome-misc';
|
import { getExtensionVersion, extrenalNavigate } from '@/utils/chrome-misc';
|
||||||
|
import { YUP_APP_BASE } from '@/constants/config';
|
||||||
|
|
||||||
let loading = true;
|
let loading = true;
|
||||||
let version = '';
|
let version = '';
|
||||||
const extensionSourceLink = 'https://github.com/andrei0x309/yup-live-chrome-extension'
|
const extensionSourceLink = 'https://github.com/andrei0x309/yup-live-chrome-extension'
|
||||||
const yupLiveSourceLink = 'https://github.com/andrei0x309/yup-live'
|
const yupLiveSourceLink = 'https://github.com/andrei0x309/yup-live'
|
||||||
const yupLiveLink = 'https://yup-live.pages.dev'
|
const yupLiveLink = 'https://yup-live.pages.dev'
|
||||||
const yupAppLink = 'https://app.yup.io'
|
const yupAppLink = YUP_APP_BASE
|
||||||
const discordLink = 'https://discord.com/invite/HnaTAXK'
|
const discordLink = 'https://discord.com/invite/HnaTAXK'
|
||||||
const yupForumLink = 'https://forum.yup.io'
|
const yupForumLink = 'https://forum.yup.io'
|
||||||
const yupDocsLink = 'https://docs.yup.io'
|
const yupDocsLink = 'https://docs.yup.io'
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { extrenalNavigate } from "@/utils/chrome-misc";
|
import { extrenalNavigate } from "@/utils/chrome-misc";
|
||||||
import { APP_BASE } from '@/constants/config'
|
import { YUP_APP_BASE } from '@/constants/config'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<a href="#app" on:click={() => extrenalNavigate(`${APP_BASE}/login`)}>
|
<a href="#app" on:click={() => extrenalNavigate(`${YUP_APP_BASE}/login`)}>
|
||||||
<svg enable-background="new 0 0 32 32" viewBox="0 0 32 32" class="w-20 mb-10 mt-8 svg-fill">
|
<svg enable-background="new 0 0 32 32" viewBox="0 0 32 32" class="w-20 mb-10 mt-8 svg-fill">
|
||||||
<g id="lock"><path d="M25,13V9c0-4.971-4.029-9-9-9c-4.971,0-9,4.029-9,9v4c-1.657,0-3,1.343-3,3v3v1v2v1c0,4.971,4.029,9,9,9h6 c4.971,0,9-4.029,9-9v-1v-2v-1v-3C28,14.342,26.656,13,25,13z M9,9c0-3.866,3.134-7,7-7c3.866,0,7,3.134,7,7v4h-2V9.002 c0-2.762-2.238-5-5-5c-2.762,0-5,2.238-5,5V13H9V9z M20,9v0.003V13h-8V9.002V9c0-2.209,1.791-4,4-4C18.209,5,20,6.791,20,9z M26,19 v1v2v1c0,3.859-3.141,7-7,7h-6c-3.859,0-7-3.141-7-7v-1v-2v-1v-3c0-0.552,0.448-1,1-1c0.667,0,1.333,0,2,0h14c0.666,0,1.332,0,2,0 c0.551,0,1,0.448,1,1V19z"/>
|
<g id="lock"><path d="M25,13V9c0-4.971-4.029-9-9-9c-4.971,0-9,4.029-9,9v4c-1.657,0-3,1.343-3,3v3v1v2v1c0,4.971,4.029,9,9,9h6 c4.971,0,9-4.029,9-9v-1v-2v-1v-3C28,14.342,26.656,13,25,13z M9,9c0-3.866,3.134-7,7-7c3.866,0,7,3.134,7,7v4h-2V9.002 c0-2.762-2.238-5-5-5c-2.762,0-5,2.238-5,5V13H9V9z M20,9v0.003V13h-8V9.002V9c0-2.209,1.791-4,4-4C18.209,5,20,6.791,20,9z M26,19 v1v2v1c0,3.859-3.141,7-7,7h-6c-3.859,0-7-3.141-7-7v-1v-2v-1v-3c0-0.552,0.448-1,1-1c0.667,0,1.333,0,2,0h14c0.666,0,1.332,0,2,0 c0.551,0,1,0.448,1,1V19z"/>
|
||||||
<path d="M16,19c-1.104,0-2,0.895-2,2c0,0.607,0.333,1.76,0.667,2.672c0.272,0.742,0.614,1.326,1.333,1.326 c0.782,0,1.061-0.578,1.334-1.316C17.672,22.768,18,21.609,18,21C18,19.895,17.104,19,16,19z"/></g>
|
<path d="M16,19c-1.104,0-2,0.895-2,2c0,0.607,0.333,1.76,0.667,2.672c0.272,0.742,0.614,1.326,1.333,1.326 c0.782,0,1.061-0.578,1.334-1.316C17.672,22.768,18,21.609,18,21C18,19.895,17.104,19,16,19z"/></g>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<div class="text-[1.6rem] mb-4 uppercase">
|
<div class="text-[1.6rem] mb-4 uppercase">
|
||||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/login`)}">
|
<a href="#app" on:click="{() => extrenalNavigate(`${YUP_APP_BASE}/auth`)}">
|
||||||
Login
|
Login on web app
|
||||||
</a>
|
|
||||||
/
|
|
||||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/sign-up`)}" >
|
|
||||||
Signup
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<a href="#app" on:click="{() => extrenalNavigate(`${APP_BASE}/login`)}">
|
<a href="#app" on:click="{() => extrenalNavigate(`${YUP_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>
|
<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>
|
</a>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { extrenalNavigate } from "@/utils/chrome-misc";
|
import { extrenalNavigate } from "@/utils/chrome-misc";
|
||||||
import ImgLoader from "@/components/ImgLoader.svelte";
|
import ImgLoader from "@/components/ImgLoader.svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { APP_BASE } from "@/constants/config";
|
import { YUP_APP_BASE } from "@/constants/config";
|
||||||
import RateWebsite from "@/components/RateWebsite.svelte";
|
import RateWebsite from "@/components/RateWebsite.svelte";
|
||||||
import { mainStore } from "@/utils/store";
|
import { mainStore } from "@/utils/store";
|
||||||
import { formatNumber, truncteEVMAddr } from "@/utils/misc";
|
import { formatNumber, truncteEVMAddr } from "@/utils/misc";
|
||||||
|
@ -19,7 +19,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
console.log($mainStore);
|
|
||||||
if ($mainStore?.user?.profile?.yup?.avatar && !$mainStore?.user?.profile?.yup?.avatar.endsWith(".mp4")) {
|
if ($mainStore?.user?.profile?.yup?.avatar && !$mainStore?.user?.profile?.yup?.avatar.endsWith(".mp4")) {
|
||||||
avatar = $mainStore?.user?.profile?.yup?.avatar;
|
avatar = $mainStore?.user?.profile?.yup?.avatar;
|
||||||
} else if ($mainStore?.user?.profile?.lens?.avatar && !$mainStore?.user?.profile?.lens?.avatar.endsWith(".mp4")) {
|
} else if ($mainStore?.user?.profile?.lens?.avatar && !$mainStore?.user?.profile?.lens?.avatar.endsWith(".mp4")) {
|
||||||
|
@ -36,12 +35,12 @@
|
||||||
|
|
||||||
<div class="h-24 leading-6 main-section">
|
<div class="h-24 leading-6 main-section">
|
||||||
<div class="flex my-2">
|
<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"
|
<span class="text-[0.6rem] mb-1">Score</span><span class="text-[0.95rem] mb-1"
|
||||||
>{$mainStore?.user?.profile?.yupScore?.toFixed(0)}</span
|
>{$mainStore?.user?.profile?.yupScore?.toFixed(0)}</span
|
||||||
><span class="text-[0.7rem]">100<br />MAX</span>
|
><span class="text-[0.7rem]">100<br />MAX</span>
|
||||||
</div>
|
</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(`${YUP_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}>
|
<ImgLoader source={avatar} bind:this={loader}>
|
||||||
<img
|
<img
|
||||||
style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1);' : '' }"
|
style="{ $mainStore.settings.theme === 'light'? 'filter: invert(1);' : '' }"
|
||||||
|
@ -82,7 +81,7 @@
|
||||||
<span class="text-[0.6rem] mt-4 -ml-1">{handle.length >= 12 ? handle.slice(0, 10) + "..." : handle}</span>
|
<span class="text-[0.6rem] mt-4 -ml-1">{handle.length >= 12 ? handle.slice(0, 10) + "..." : handle}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</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"
|
<span class="text-[0.6rem] mb-1">Influence</span><span class="text-[0.95rem] mb-1"
|
||||||
>{$mainStore?.user?.profile?.yup?.weight}</span
|
>{$mainStore?.user?.profile?.yup?.weight}</span
|
||||||
><span class="text-[0.7rem]">10<br />MAX</span>
|
><span class="text-[0.7rem]">10<br />MAX</span>
|
||||||
|
|
|
@ -23,7 +23,6 @@ onMount(async () => {
|
||||||
})
|
})
|
||||||
pastNotifsPromise = getNotifStorage()
|
pastNotifsPromise = getNotifStorage()
|
||||||
|
|
||||||
console.log(notifs);
|
|
||||||
loading = false;
|
loading = false;
|
||||||
clearNotifications($mainStore).then(
|
clearNotifications($mainStore).then(
|
||||||
() => {
|
() => {
|
||||||
|
@ -68,7 +67,7 @@ const changeNotifsType = async (t : string[] | null) => {
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text-[0.75rem] py-1">
|
<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(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>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
{#each notifs as notif}
|
{#each notifs as notif}
|
||||||
|
|
|
@ -45,7 +45,6 @@ const setSettingsLocal = async (setting: string, value = '') => {
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
settings = $mainStore.settings
|
settings = $mainStore.settings
|
||||||
console.log(settings)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -138,6 +137,36 @@ onMount(async () => {
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{:else}
|
{:else}
|
||||||
|
|
|
@ -49,6 +49,13 @@ export const storageDefault = {
|
||||||
refilNotifTimestamp: 0,
|
refilNotifTimestamp: 0,
|
||||||
enableRightClick: false,
|
enableRightClick: false,
|
||||||
enableRightClickNotif: false,
|
enableRightClickNotif: false,
|
||||||
|
lastLoginNotif: 0,
|
||||||
|
enableCommentNotif: false,
|
||||||
|
enableMentionNotif: false,
|
||||||
|
enableFollowNotif: false,
|
||||||
|
lastfollowNotif: 0,
|
||||||
|
lastCommentNotif: 0,
|
||||||
|
lastMentionNotif: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,8 +68,6 @@ export const lastRewardNotifDefault = {
|
||||||
id: '',
|
id: '',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type StorageType = typeof storageDefault
|
export type StorageType = typeof storageDefault
|
||||||
|
|
||||||
export const wipeStorage = async () => {
|
export const wipeStorage = async () => {
|
||||||
|
@ -148,3 +153,14 @@ export const getSettings = async () => {
|
||||||
return store ? store.store.settings as StorageType['settings'] : storageDefault.settings as StorageType['settings']
|
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
|
avatar: string
|
||||||
}[]
|
}[]
|
||||||
message?: string
|
message?: string
|
||||||
|
seen: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue