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

huh. #758

Merged
merged 13 commits into from
Jan 31, 2024
13 changes: 9 additions & 4 deletions src/components/nav/NavDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@
<template v-for="vid in collapsedFavorites">
<v-list-item
v-if="vid"
:key="vid.id"
:key="vid.key"
:class="{ 'v-list-item--active': $route.path.startsWith(`/channel/${vid.channel.id}`) }"
@click="$router.push(`/channel/${vid.channel.id}`).catch(() => {})"
>
<v-list-item-avatar :size="30" :class="{ outlined: isLive(vid) }">
<ChannelImg :channel="vid.channel" :size="30" />
</v-list-item-avatar>
<ChannelInfo :channel="vid.channel" no-subscriber-count no-group />
<v-list-item-action-text v-if="vid.id" :key="'liveclock' + vid.id + tick">
<v-list-item-action-text v-if="vid.id" :key="'liveclock' + vid.key + tick">
<div :class="isLive(vid) ? 'ch-live' : 'ch-upcoming'">
<v-avatar v-if="vid.host_channel" :size="20">
<ChannelImg :channel="vid.host_channel" :size="20" />
Expand Down Expand Up @@ -215,7 +215,7 @@ export default {
.filter((x) => favoritesSet.has(x.channel.id))
.forEach((x) => {
if (!existingChs.has(x.channel.id)) {
existingChs.set(x.channel.id, x)
existingChs.set(x.channel.id, { ...x, key: `${x.channel.id}${x.id}` });
}
});

Expand All @@ -224,7 +224,12 @@ export default {
.filter((x) => x.mentions?.length && !blockedSet.has(x.channel.id))
.forEach((x) => x.mentions
.filter(({ id }) => favoritesSet.has(id) && !existingChs.has(id) && !blockedSet.has(id))
.forEach((m) => existingChs.set(m.id, { ...x, channel: m, host_channel: x.channel }))
.forEach((m) => existingChs.set(m.id, {
...x,
channel: m,
host_channel: x.channel,
key: `${m.id}${x.id}`,
}))
);

// remainder:
Expand Down
5 changes: 3 additions & 2 deletions src/locales/en/ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,8 @@ channelRequest:
VtuberRequirementText: >-
A minimum of 20K subscribers is required for independents. Vtubers as part
of existing orgs will be accepted. <br /><br />New Orgs will be created
depending on the average subscriber count.
depending on the average subscriber count.<br /><br />Twitch streamers must
have an official YouTube channel to be indexed.
ClipperRequirementText: >-
For clippers, it must be at least 2 months old and post regularly, or post
more than 20 clips in one month. Spamming of short clips every day, posting
Expand All @@ -760,4 +761,4 @@ channelRequest:
Deletion should only be requested if you are the channel owner(s), please
provide contact information so we can verify this.
PageTitle: Holodex Channel Request
ChannelURLErrorFeedback: Must be https://www.youtube.com/channel/UC_____
ChannelURLErrorFeedback: Must be https://www.youtube.com/channel/UC_____ or https://www.youtube.com/@_____
2 changes: 1 addition & 1 deletion src/utils/backend-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export default {
return axiosInstance.post(`/songs/latest?c=${dt}`, {
channel_id: channelId,
video_id: videoId,
limit: 100,
limit: 1000,
});
},
tryCreateSong(songObj, jwt) {
Expand Down
2 changes: 2 additions & 0 deletions src/utils/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export const ORGS_PREFIX = Object.freeze({

export const CHANNEL_URL_REGEX = /(?:(?:https?:|)\/\/|)(?:www\.|)(?:youtube\.com\/|\/?)channel\/(?<id>[\w-]+)/i;

export const CHANNEL_OR_HANDLE_REGEX = /(?:(?:https?:|)\/\/|)(?:www\.|)(?:youtube\.com\/|\/?)(?:channel\/|@)(?<id>[\w-]+)/i;

export const VIDEO_URL_REGEX = /(?:(?:https?:|)\/\/|)((?:www|m)\.|)(?<domain>youtube\.com|youtu\.be|holodex\.net)\/(?:[\w-]+\?v=|embed|v|watch|live|)\/?(?<id>[\w-]{11})/i;

export const TWITCH_VIDEO_URL_REGEX = /(?:(?:https?:|)\/\/|)twitch\.tv\/(?<id>[\w-]+)/i;
Expand Down
5 changes: 4 additions & 1 deletion src/utils/mv-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,14 @@ export const desktopPresets = Object.freeze([
{ layout: "AASR,SAGYchat,ARGH,GRGH,MRGH", name: "Sports Fes 1" },
{ layout: "AAMM,SAGYchat,AMGG,ASGG,GMGG,GSGG,MAGG,MGGG,MMGG,MSGG", name: "Sports Fes 2" },
{ layout: "GAMM,GMMM,AAGG,AGGG,AMGG,ASGG,SAGG,SGGG,SMGG,SSGG", name: "Sports Fes 3" },
{ layout: "AAIK,IAIK,QAIK,AKGH,GKGH,MKGH,SKGH,SRGH,ARGH,MRGH,GRGH", name: "Amoung Us 3", default: 11 },
{ layout: "AAIK,IAIK,QAIK,AKGH,GKGH,MKGH,SKGH,SRGH,ARGH,MRGH,GRGH", name: "Among Us 3", default: 11 },
{ layout: "AAGI,GAGI,MAGI,AIGI,GIGI,MIGI,SIGI,SQGI,AQGI,MQGI,GQGI,SAGI", name: "4x3", default: 12 },
{ layout: "AAMM,MMGG,AMGG,GMGG,MGGG,SSGG,MSGG,MAGG,SMGG,SGGG,SAGG,ASGG,GSGG", name: "13🎞️", default: 13 },
{ layout: "AMJM,OMFG,OGFG,TGFG,JMFG,AAJM,OAFG,TMFG,JAFG,TSFG,OSFG,JGFG,TAFG,JSFG", name: "14🎞️", default: 14 },
{ layout: "AGGG,MMGG,MGGG,SGGG,GMGG,AAGG,MAGG,SMGG,GAGG,SSGG,MSGG,GGGG,SAGG,GSGG,AMGG,ASGG", name: "4x4", default: 16 },
{ layout: "AAHY,HAHY,OAFYchat,TAFYchat", name: "2📱 2💬" },
{ layout: "AAGY,GAGY,MAGY,SAGYchat", name: "3📱 1💬" },
{ layout: "AAMM,AMMM,MAHY,TAFYchat2", name: "2🎞️ 1📱 1💬" },
]);

export const mobilePresets = Object.freeze([
Expand Down
17 changes: 10 additions & 7 deletions src/views/AddChannelRequest.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
v-else
v-model="link"
label="Channel URL"
placeholder="https://www.youtube.com/channel/UC_____"
hint="https://www.youtube.com/channel/UC_____"
placeholder="https://www.youtube.com/channel/UC_____ or https://www.youtube.com/@_____"
hint="https://www.youtube.com/channel/UC_____ or https://www.youtube.com/@_____"
:rules="[channelURLRule]"
/>
<v-text-field
Expand Down Expand Up @@ -236,14 +236,14 @@ export default {
linkRule: (v) => !!v.match(/^https?:\/\/[\w-]+(\.[\w-]+)+\.?(\/\S*)?/) || "Invalid url",
twitterRule: (v) => !v || !!v.match(/^@.*$/) || "@ABC",
channelURLRule(v) {
const REGEX = /(?:https?:\/\/)(?:www\.)?youtu(?:be\.com\/)(?:channel)\/([\w-_]*)$/i;
const REGEX = /(?:https?:\/\/)(?:www\.)?youtu(?:be\.com\/)(?:channel\/|@)([\w-_]*)$/i;

const cid = v.match(REGEX);
console.log(cid);
return (
(cid
&& !cid[0].includes("/c/")
&& cid[1].length > 12
&& (cid[1].length > 12 || cid[0].includes('@'))
&& cid[0].startsWith("ht"))
|| this.$t("channelRequest.ChannelURLErrorFeedback")
);
Expand All @@ -264,16 +264,19 @@ export default {
},

async onSubmit() {
let handle = null;
if (this.type === ADD_VTUBER || this.type === ADD_CLIPPER) {
// validate it's not added already:
const regex = /(?:https?:\/\/)(?:www\.)?youtu(?:be\.com\/)(?:channel)\/([\w\-_]*)/gi;
const regex = /(?:https?:\/\/)(?:www\.)?youtu(?:be\.com\/)(?:channel\/|@)([\w\-_]*)/gi;
const matches = [...this.link.matchAll(regex)];
const id = matches?.[0]?.[1];
let id = matches?.[0]?.[1];
handle = this.link.includes('@')
id = handle ? '@' + id.toLowerCase() : id;

try {
const exists = id && (await backendApi.channel(id));
if (exists && exists.data && exists.data.id) {
this.$router.push({ path: `/channel/${id}` });
this.$router.push({ path: `/channel/${exists.data.id}` });
return;
}
} catch (e) {
Expand Down
70 changes: 49 additions & 21 deletions src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
</template>

<script lang="ts">
import open from "oauth-open";
// import open from "oauth-open";
import api from "@/utils/backend-api";
import UserCard from "@/components/user/UserCard.vue";
import copyToClipboard from "@/mixins/copyToClipboard";
Expand Down Expand Up @@ -213,7 +213,29 @@ export default {
const params = new URL(window.location.href).searchParams;
const service = params.get("service");
const jwt = params.get("jwt");
if (service === "twitter" && jwt) {
if (service === "discord" && window.location.hash) {
// the hash is #token_type=Bearer&access_token=yG7BNWhnqcQmXaOQEJEzw2nu7IgeIK&expires_in=604800&scope=identify
// parse the hash
console.log("analyzing hash", window.location.hash);
const hash = window.location.hash.substring(1);
const discordAuthParams = new URLSearchParams(hash);
// const tokenType = discordAuthParams.get('token_type');
const accessToken = discordAuthParams.get("access_token");
// const expiresIn = discordAuthParams.get('expires_in');
// const scope = discordAuthParams.get('scope');
const resp = await api.login(
this.$store.state.userdata.jwt,
accessToken,
"discord",
);
// console.log(resp);
this.$store.commit("setUser", resp.data);
this.$gtag.event("login", {
event_label: "discord",
});

this.$store.dispatch("favorites/resetFavorites");
} else if (service === "twitter" && jwt) {
const twitterTempJWT = jwt;
const resp = await api.login(
this.$store.state.userdata.jwt,
Expand Down Expand Up @@ -253,29 +275,35 @@ export default {
},
async loginDiscord() {
// redirect location:
const redirectUri = `${window.location.protocol}//${window.location.host}/discord`;
const redirectUri = `${window.location.protocol}//${window.location.host}/login?service=discord`;

// redirect to url
window.open(`https://discord.com/api/oauth2/authorize?client_id=793619250115379262&redirect_uri=${encodeURIComponent(
redirectUri,
)}&response_type=token&scope=identify`);

// out:
// {token_type: "Bearer", access_token: "<SOMEACCESSTOKEN>", expires_in: "604800", scope: "identify"}
open(
`https://discord.com/api/oauth2/authorize?client_id=793619250115379262&redirect_uri=${encodeURIComponent(
redirectUri,
)}&response_type=token&scope=identify`,
async (err, out) => {
const resp = await api.login(
this.$store.state.userdata.jwt,
out.access_token,
"discord",
);
// console.log(resp);
this.$store.commit("setUser", resp.data);
this.$gtag.event("login", {
event_label: "discord",
});
// open(
// `https://discord.com/api/oauth2/authorize?client_id=793619250115379262&redirect_uri=${encodeURIComponent(
// redirectUri,
// )}&response_type=token&scope=identify`,
// async (err, out) => {
// console.log(err, out)
// const resp = await api.login(
// this.$store.state.userdata.jwt,
// out.access_token,
// "discord",
// );
// // console.log(resp);
// this.$store.commit("setUser", resp.data);
// this.$gtag.event("login", {
// event_label: "discord",
// });

this.$store.dispatch("favorites/resetFavorites");
},
);
// this.$store.dispatch("favorites/resetFavorites");
// },
// );
},
async loginTwitter() {
window.location.href = `${apiURI}/v2/user/login/twitter`;
Expand Down