chore: monorepo

This commit is contained in:
2023-12-25 14:28:39 +07:00
parent a6da07cd3f
commit 227c2ddefa
374 changed files with 19966 additions and 12758 deletions

View File

@@ -0,0 +1,311 @@
export const FETCH_LIMIT = 20;
export const HASHTAGS = [
{ hashtag: "#food" },
{ hashtag: "#gaming" },
{ hashtag: "#nsfw" },
{ hashtag: "#bitcoin" },
{ hashtag: "#nostr" },
{ hashtag: "#nostrdesign" },
{ hashtag: "#security" },
{ hashtag: "#zap" },
{ hashtag: "#LFG" },
{ hashtag: "#zapchain" },
{ hashtag: "#shitcoin" },
{ hashtag: "#plebchain" },
{ hashtag: "#nodes" },
{ hashtag: "#hodl" },
{ hashtag: "#stacksats" },
{ hashtag: "#nokyc" },
{ hashtag: "#meme" },
{ hashtag: "#memes" },
{ hashtag: "#memestr" },
{ hashtag: "#nostriches" },
{ hashtag: "#dev" },
{ hashtag: "#anime" },
{ hashtag: "#waifu" },
{ hashtag: "#manga" },
{ hashtag: "#lume" },
{ hashtag: "#snort" },
{ hashtag: "#damus" },
{ hashtag: "#primal" },
];
export const WIDGET_KIND = {
user: 1,
thread: 2,
group: 3,
article: 4,
file: 5,
trendingNotes: 6,
trendingAccounts: 7,
topic: 8,
hashtag: 9,
notification: 9998,
newsfeed: 9999,
list: 10000,
};
export const TOPICS = [
{
title: "Gaming",
content: [
"#gamestr",
"#gaming",
"#gamer",
"#ps",
"#playstation",
"#videogames",
"#game",
"#xbox",
"#games",
"#twitch",
"#fortnite",
"#pc",
"#pcgaming",
"#gamers",
"#gamingcommunity",
"#switch",
"#gamergirl",
"#nintendo",
"#gta",
"#callofduty",
"#pubg",
"#videogame",
"#esports",
"#genshinimpact",
"#honkaiimpact",
"#warthunder",
"#hoyoverse",
"#arknights",
"#soullike",
"#eldenring",
"#steam",
"#pubg",
"#cs2",
"#apexlegends",
"#baldurgate3",
"#starfield",
"#gta6",
"#gameoftheyear",
"#darksoul",
"#batterfield",
"#dota",
"#rpg",
"#thewitcher",
"#rogally",
"#rog",
"#indiegames",
"#indiedev",
"#gamedev",
],
},
{
title: "Music",
content: [
"#audiostr",
"#musicstr",
"#music",
"#love",
"#hiphop",
"#rap",
"#art",
"#musician",
"#artist",
"#musica",
"#singer",
"#dj",
"#rock",
"#dance",
"#guitar",
"#song",
"#newmusic",
"#producer",
"#life",
"#rapper",
"#party",
"#fashion",
"#explorepage",
"#viral",
"#beats",
"#dvd",
"#amass",
"#bluray",
"#Blu_Ray",
"#taylor",
],
},
{
title: "Photography",
content: [
"#photography",
"#photooftheday",
"#love",
"#photo",
"#nature",
"#picoftheday",
"#photographer",
"#beautiful",
"#fashion",
"#travel",
"#photoshoot",
"#naturephotography",
"#model",
"#me",
"#smile",
"#style",
"#happy",
"#likes",
"#myself",
],
},
{
title: "Art",
content: [
"#nostrdesign",
"#artstr",
"#art",
"#artist",
"#drawing",
"#artwork",
"#painting",
"#fashion",
"#beautiful",
"#illustration",
"#digitalart",
"#design",
"#nature",
"#photo",
"#sketch",
"#style",
"#arte",
"#happy",
"#cute",
"#draw",
"#artoftheday",
],
},
{
title: "Movie",
content: [
"#filmstr",
"#moviestr",
"#movies",
"#movie",
"#film",
"#cinema",
"#films",
"#hollywood",
"#actor",
"#cinematography",
"#actress",
"#netflix",
"#moviescenes",
"#music",
"#filmmaking",
"#horror",
"#bollywood",
"#movienight",
"#photography",
"#comedy",
"#cinephile",
"#cine",
"#tv",
"#director",
"#horrormovies",
"#drama",
"#filmmaker",
],
},
{
title: "Technology",
content: [
"#apple",
"#xiaomi",
"#huawei",
"#ai",
"#oppo",
"#nostr",
"#technology",
"#tech",
"#innovation",
"#engineering",
"#business",
"#iphone",
"#technews",
"#science",
"#gadgets",
"#electronics",
"#android",
"#software",
"#programming",
"#smartphone",
"#samsung",
"#coding",
"#computer",
"#security",
"#gadget",
"#mobile",
"#technologynews",
"#opensource",
"#tor",
"#bitcoin",
"#lightning",
],
},
{
title: "Anime",
content: [
"#animestr",
"#anime",
"#manga",
"#otaku",
"#animeart",
"#animegirl",
"#cosplay",
"#weeb",
"#onepiece",
"#demonslayer",
"#animeworld",
"#aot",
"#fanart",
"#vocaloid",
"#vtuber",
"#fate",
"#hololive",
"#hololivemeet",
"#pixiv",
"#waifu",
],
},
{
title: "NSFW",
content: [
"#pornstr",
"#porn",
"#nsfw",
"#bdsm",
"#lewd",
"#kink",
"#sexy",
"#loli",
"#hentai",
"#ntr",
],
},
];
export const QUOTES = [
"You can learn more about nostr here: https://usenostr.org",
"Nostr has a lot of awesome clients, you can spend a bit of time to try https://snort.social",
"Nostr has a lot of awesome clients, you can spend a bit of time to try https://iris.to",
"Nostr has a lot of awesome clients, you can spend a bit of time to try https://primal.net",
"Nostr has a lot of awesome clients, you can spend a bit of time to try https://nostrudel.ninja",
"If you're using iOS, you can use Nostr with https://damus.io",
"If you're using Android, you can use Nostr with Amethyst",
"If you want to curate and share your interests on Nostr, you can use https://pinstr.app",
"If you want to post anonymously on Nostr, you can use https://www.get-tao.app",
"If you want to read in-depth content and high quality insights, you can use https://habla.news",
"You can send secure messages on Nostr with https://0xchat.com/",
"Are you a fan of following topics, instead of people? Use https://zapddit.com",
];

View File

@@ -0,0 +1 @@
export const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));

View File

@@ -0,0 +1,67 @@
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import updateLocale from "dayjs/plugin/updateLocale";
import { nip19 } from "nostr-tools";
dayjs.extend(relativeTime);
dayjs.extend(updateLocale);
dayjs.updateLocale("en", {
relativeTime: {
past: "%s ago",
s: "just now",
m: "1m",
mm: "%dm",
h: "1h",
hh: "%dh",
d: "1d",
dd: "%dd",
},
});
export function formatCreatedAt(time: number, message = false) {
let formated: string;
const now = dayjs();
const inputTime = dayjs.unix(time);
const diff = now.diff(inputTime, "hour");
if (message) {
if (diff < 12) {
formated = inputTime.format("HH:mm A");
} else {
formated = inputTime.format("MMM DD");
}
} else {
if (diff < 24) {
formated = inputTime.from(now, true);
} else {
formated = inputTime.format("MMM DD");
}
}
return formated;
}
export function displayNpub(pubkey: string, len: number) {
const npub = pubkey.startsWith("npub1")
? pubkey
: (nip19.npubEncode(pubkey) as string);
if (npub.length <= len) return npub;
const separator = " ... ";
const sepLen = separator.length;
const charsToShow = len - sepLen;
const frontChars = Math.ceil(charsToShow / 2);
const backChars = Math.floor(charsToShow / 2);
return (
npub.substr(0, frontChars) +
separator +
npub.substr(npub.length - backChars)
);
}
// convert number to K, M, B, T, etc.
export const compactNumber = Intl.NumberFormat("en", { notation: "compact" });

View File

@@ -0,0 +1,25 @@
import { useEffect, useState } from "react";
const getOnLineStatus = () =>
typeof navigator !== "undefined" && typeof navigator.onLine === "boolean"
? navigator.onLine
: true;
export function useNetworkStatus() {
const [status, setStatus] = useState(getOnLineStatus());
const setOnline = () => setStatus(true);
const setOffline = () => setStatus(false);
useEffect(() => {
window.addEventListener("online", setOnline);
window.addEventListener("offline", setOffline);
return () => {
window.removeEventListener("online", setOnline);
window.removeEventListener("offline", setOffline);
};
}, []);
return status;
}

View File

@@ -0,0 +1,26 @@
import { type Opengraph } from "@lume/types";
import { useQuery } from "@tanstack/react-query";
import { invoke } from "@tauri-apps/api/primitives";
export function useOpenGraph(url: string) {
const { status, data, error } = useQuery({
queryKey: ["opg", url],
queryFn: async () => {
const res: Opengraph = await invoke("opengraph", { url });
if (!res) {
throw new Error("fetch preview failed");
}
return res;
},
staleTime: Infinity,
refetchOnWindowFocus: false,
refetchOnMount: false,
refetchOnReconnect: false,
});
return {
status,
data,
error,
};
}

View File

@@ -0,0 +1,15 @@
export function fileType(url: string) {
if (url.match(/\.(jpg|jpeg|gif|png|webp|avif|tiff)$/)) {
return "image";
}
if (url.match(/\.(mp4|mov|webm|wmv|flv|mts|avi|ogv|mkv)$/)) {
return "video";
}
if (url.match(/\.(mp3|ogg|wav)$/)) {
return "audio";
}
return "link";
}

View File

@@ -0,0 +1,16 @@
import {
isPermissionGranted,
requestPermission,
sendNotification,
} from "@tauri-apps/plugin-notification";
export async function sendNativeNotification(content: string, title?: string) {
let permissionGranted = await isPermissionGranted();
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === "granted";
}
if (permissionGranted) {
sendNotification({ title: title || "Lume", body: content });
}
}