Skip to content

Commit

Permalink
twitter icon + link, refresh animation, readme
Browse files Browse the repository at this point in the history
  • Loading branch information
zigamacele committed Mar 7, 2023
1 parent b02c4bc commit 23fdff9
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 70 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Liver
# Liver ![version](https://img.shields.io/badge/Version-v0.0.2-pink?style=for-the-badge&logo)

<a><img align="right" src="https://i.imgur.com/F9qenDY.png"></a>

### Check if you favorite VTuber is live!

Expand All @@ -13,8 +15,10 @@ _Insert video here_

## Images

<img src="https://i.imgur.com/eYe2wI5.png" width="280"><img src="https://i.imgur.com/Iq9BXVd.png" width="280">
<img src="https://i.imgur.com/QIWMuNI.png" width="280"><img src="https://i.imgur.com/4Ty40Wq.png" width="280">
<img src="https://i.imgur.com/FTHCArK.png" width="280"><img src="https://i.imgur.com/wLZK69d.png" width="280">
<img src="https://i.imgur.com/RViLUqa.png" width="280"><img src="https://i.imgur.com/rZykb4w.png" width="280">

<br />

## Technologies used

Expand All @@ -23,6 +27,8 @@ _Insert video here_
-TailwindCSS \
-Chrome Storage API

<br />

## Use extension with your own API key

Make sure you have [Node.js](https://nodejs.org/) installed. \
Expand All @@ -40,7 +46,6 @@ Download extension from Releases and extract it outside of repo you just cloned.
Get your own API key from [Holodex](https://docs.holodex.net/docs/holodex/ZG9jOjQ2Nzk1-getting-started)

Go back into the repo you just cloned, create .env file and paste in your API key.
<img src="https://i.imgur.com/8fpa3yb.png" width="280">

```sh
NEXT_PUBLIC_HOLODEX=YOUR_API_KEY
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "liver-app",
"version": "0.1.0",
"version": "0.0.2",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
125 changes: 80 additions & 45 deletions src/Components/DisplayMyLivers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import ClipLoader from 'react-spinners/ClipLoader';
// @ts-ignore
import PulseDot from 'react-pulse-dot';

import { AiFillTwitterCircle } from 'react-icons/ai';

export default function DisplayMyLivers() {
const [displayLivers, setDisplayLivers] = useState([]);
const [liverStatus, setLiverStatus] = useState<any>({});
const [databaseInfo, setDatabaseInfo] = useState<any>({});
const [liverStatus, setLiverStatus] = useState({});
const [databaseInfo, setDatabaseInfo] = useState<vtubersFromDB>({});
const [loading, setLoading] = useState(true);
const [APIResponse, setAPIResponse] = useState<any>([]);
const axios = require('axios');

interface vtuberInfo {
name: string;
imageURL: string;
channelID: string;
retired: boolean;
twitter: string;
}

interface vtubersFromDB {
[key: string]: vtuberInfo;
}

useEffect(() => {
getMyLivers();
getAPIData();
Expand All @@ -28,7 +42,7 @@ export default function DisplayMyLivers() {
}, [APIResponse]);

function getMyLivers() {
chrome.storage.local.get('myLivers', function (data: any) {
chrome.storage.local.get('myLivers', function (data) {
if (data.myLivers === undefined || data.myLivers.length === 0) {
return;
}
Expand All @@ -39,8 +53,8 @@ export default function DisplayMyLivers() {
async function databaseSearch() {
let tempDatabase = {};
displayLivers.forEach((memberID) => {
database.forEach((branch: any) => {
branch.members.forEach((member: any) => {
database.forEach((branch) => {
branch.members.forEach((member) => {
if (member.channelID === memberID) {
tempDatabase = { ...tempDatabase, [memberID]: member };
}
Expand All @@ -61,7 +75,6 @@ export default function DisplayMyLivers() {
try {
const response = await axios.get(url, config);
setAPIResponse(response.data);
console.log('api', response.data);
} catch (error) {
console.log(error);
}
Expand All @@ -87,47 +100,69 @@ export default function DisplayMyLivers() {
});
}

const test = displayLivers.map((memberID) => {
const url = `https://youtube.com/channel/${memberID}/live`;
return (
<div key={memberID}>
{!databaseInfo[memberID] ? null : (
<div className="relative">
<img
src={databaseInfo[memberID].imageURL}
alt={databaseInfo[memberID].name}
className="rounded-full h-20 liver border-4 border-white dark:border-slate-700 bg-slate-200 dark:bg-slate-800 cursor-pointer hover:opacity-80"
onClick={(e) => {
chrome.tabs.create({ url: url });
}}
/>

{loading ? (
<div className="absolute left-[4.5em] bottom-[4.5em] bg-white p-1 pb-0 rounded-full dark:bg-slate-700">
<ClipLoader size={15} />
</div>
) : (
<div className="absolute left-[4em] bottom-[4em]">
{liverStatus[memberID] === 'offline' ? (
<div className="absolute left-[-1em] bottom-[0.7em] py-0.5 px-1.5 bg-white dark:bg-slate-700 dark:text-white rounded-full">
<p className="text-[10px]">OFFLINE</p>
</div>
) : (
<PulseDot
className="absolute text-xl bottom-[-0.15em]"
color="danger"
/>
)}
</div>
)}
</div>
)}
</div>
);
});
function handleTwitter(memberID: string) {
database.forEach((branch) => {
branch.members.forEach((member) => {
const url = 'https://twitter.com/';
if (member.channelID === memberID) {
chrome.tabs.create({ url: url + member.twitter });
}
});
});
}

return (
<div className="my-2">
<div className="flex flex-wrap justify-center gap-2">{test}</div>
<div className="flex flex-wrap justify-center gap-3">
{displayLivers.map((memberID) => {
const url = `https://youtube.com/channel/${memberID}/live`;
return (
<div key={memberID}>
{!databaseInfo[memberID] ? null : (
<div className="relative">
<img
src={databaseInfo[memberID].imageURL}
alt={databaseInfo[memberID].name}
className="rounded-full h-20 liver border-4 border-white dark:border-slate-700 bg-slate-200 dark:bg-slate-800 cursor-pointer hover:opacity-80"
onClick={(e) => {
chrome.tabs.create({ url: url });
}}
/>
<div
className="text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 cursor-pointer absolute left-[4em] bottom-[4em]"
onClick={() => handleTwitter(memberID)}
>
<AiFillTwitterCircle className="absolute text-lg left-[1.15em] bottom-[-0.85em] z-10 " />
<span className="absolute text-xl left-[0.975em] bottom-[-0.82em] bg-white dark:bg-slate-700 h-5 w-5 rounded-full"></span>
</div>

{loading ? (
<div className="absolute left-[4.5em] bottom-[4.5em] bg-white p-1 pb-0 rounded-full dark:bg-slate-700">
<ClipLoader size={15} />
</div>
) : (
<div className="absolute left-[4em] bottom-[4em]">
{liverStatus[memberID] === 'offline' ? (
<div className="absolute left-[-1em] bottom-[0.7em] py-0.5 px-1.5 bg-white dark:bg-slate-700 dark:text-white rounded-full">
<p className="text-[10px]">OFFLINE</p>
</div>
) : (
<div>
<PulseDot
className="absolute text-xl bottom-[-0.15em] z-10"
color="danger"
/>
<span className="absolute text-xl left-[0.3em] bottom-[0.17em] bg-white dark:bg-slate-700 h-7 w-7 rounded-full"></span>
</div>
)}
</div>
)}
</div>
)}
</div>
);
})}
</div>
</div>
);
}
6 changes: 3 additions & 3 deletions src/Components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function Navigation() {
}, []);

function fetchChromeStorage() {
chrome.storage.local.get('darkMode', function (data: any) {
chrome.storage.local.get('darkMode', function (data) {
if (data.darkMode === undefined) {
return;
}
Expand All @@ -43,7 +43,7 @@ export default function Navigation() {
document.documentElement.classList.remove('dark');
setDarkMode(data.darkMode);
});
chrome.storage.local.get('goToSettings', function (data: any) {
chrome.storage.local.get('goToSettings', function (data) {
if (data.goToSettings === undefined) {
return;
}
Expand All @@ -64,7 +64,7 @@ export default function Navigation() {
<div className="flex items-center gap-2 dark:text-blue-500 text-slate-700">
<div className="bg-slate-200 dark:bg-slate-700 rounded py-1.5 px-2">
<ArrowPathIcon
className="h-5 w-5 cursor-pointer hover:dark:text-blue-400 hover:text-slate-500"
className="h-5 w-5 cursor-pointer hover:dark:text-blue-400 hover:text-slate-500 hover:animate-spin"
onClick={handleReload}
/>
</div>
Expand Down
7 changes: 4 additions & 3 deletions src/Components/SelectLiver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import React, { useEffect, useState } from 'react';
import { CheckCircleIcon } from '@heroicons/react/24/solid';

export default function SelectLiver() {
const [selectedLivers, setSelectedLivers] = useState<any>([]);
const [selectedLivers, setSelectedLivers] = useState<string[]>([]);

useEffect(() => {
chrome.storage.local.get('myLivers', function (data: any) {
chrome.storage.local.get('myLivers', function (data) {
setSelectedLivers([...data.myLivers]);
});
}, []);

function handleARLiver(memberID: string) {
let liversArray: string[] = [];
chrome.storage.local.get('myLivers', function (data: any) {
chrome.storage.local.get('myLivers', function (data) {
if (data.myLivers === undefined || data.myLivers.length === 0) {
chrome.storage.local.set({ myLivers: [memberID] });
setSelectedLivers([memberID]);
Expand Down
Loading

0 comments on commit 23fdff9

Please sign in to comment.