Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,12 @@
},
"incognito": {
"title": "Inkognito Modus bis {{time}}"
},
"communityNotes": {
"title": "Community Note",
"rate": "Diese Notiz bewerten",
"add": "Notiz schreiben",
"readMore": "Mehr lesen...",
"none": "keine"
}
}
7 changes: 7 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,12 @@
},
"incognito": {
"title": "Incognito mode until {{time}}"
},
"communityNotes": {
"title": "Community Note",
"rate": "Rate this note",
"add": "Write a note",
"readMore": "Read more...",
"none": "none"
}
}
22 changes: 22 additions & 0 deletions src/common/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ export async function setTheme({ isDark }) {
);
}

// Community Notes

export async function getCommunityNotes({ videoUrl }) {
return sendMessageToBackground(
messages.COMMUNITY_NOTES_GET,
{ videoUrl },
);
}

// ------------------------------------------------------------------------------------------------------------------------
// Hooks
// ------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -208,3 +217,16 @@ export function useVideoAnalytics({ videoUrl, accountIds }) {
data: query.data?.data,
};
}

export function useCommunityNotes({ videoUrl }) {
const query = useQuery({
queryKey: ['community-notes', videoUrl],
queryFn: () => getCommunityNotes({ videoUrl }),
enabled: !!videoUrl,
});

return {
...query,
data: query.data?.data,
};
}
11 changes: 11 additions & 0 deletions src/entries/background/common/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ export async function getVideoAnalytics({ videoUrl, accountIds }) {
return analytics;
}

export async function getCommunityNotes({ videoUrl }) {
const { data: notes } = await api('community/notes/for-video', {
token: await storageGetToken(),
query: {
video_url: videoUrl,
},
});

return notes;
}

export async function updateUserIncognitoMode({ length }) {
const { data } = await api('extension/visibility', {
method: 'POST',
Expand Down
1 change: 1 addition & 0 deletions src/entries/background/common/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ async function getResponse(type, data) {
[messages.REACTIONS_GET_FOR_VIDEO]: api.getReactionsForVideo,
[messages.REACTIONS_GET_ORIGINAL_VIDEOS]: api.getOriginalVideosForVideo,
[messages.VIDEO_ANALYTICS_GET]: api.getVideoAnalytics,
[messages.COMMUNITY_NOTES_GET]: api.getCommunityNotes,
[messages.TOGGLE_INCOGNITO_MODE]: api.updateUserIncognitoMode,
};

Expand Down
3 changes: 3 additions & 0 deletions src/entries/contentScript/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { useBackgroundEvents } from '~/entries/contentScript/hooks/useBackground
import AnalyticsNotice from '~/entries/contentScript/components/AnalyticsNotice';
import Footer from '~/entries/contentScript/components/Footer';
import { storageGetCompact, storageSetCompact } from '~/entries/background/common/storage';
import CommunityNoteNotice from '~/entries/contentScript/components/CommunityNoteNotice';

function App() {
const { t, i18n } = useTranslation();
Expand Down Expand Up @@ -156,6 +157,8 @@ function App() {

<ReactionPolicyNotice />

<CommunityNoteNotice />

{state !== STATE_LIVE && (
<ReactionsHistoryNotice />
)}
Expand Down
2 changes: 2 additions & 0 deletions src/entries/contentScript/components/Card.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function Card({
green: 'bg-[#01FF94]', // TODO
red: 'bg-[#FF5C00]',
yellow: 'bg-[#FFA800]',
dashed: 'border-2 border-dashed border-gray-200 dark:border-gray-600',
// Brand
primary: 'bg-gradient-to-r from-primary-gradient-from to-primary-gradient-to',
'brand-viewer': 'bg-gradient-to-r from-brand-viewer-gradient-from to-brand-viewer-gradient-to',
Expand Down Expand Up @@ -129,6 +130,7 @@ Card.propTypes = {
'green',
'red',
'yellow',
'dashed',
'brand-viewer',
'brand-creator',
'primary',
Expand Down
104 changes: 104 additions & 0 deletions src/entries/contentScript/components/CommunityNoteNotice.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import classNames from 'classnames';
import Card from '~/entries/contentScript/components/Card';
import { useAppStore } from '~/entries/contentScript/state';
import { useCommunityNotes } from '~/common/bridge';
import { usePage } from '~/hooks/usePage';
import { buildFrontendUrl } from '~/common/utility';
import { strLimit } from '~/common/pretty';

function CommunityNoteNotice() {
const { t } = useTranslation();
const compact = useAppStore((state) => state.isCompact);

const { currentUrl } = usePage();
const [isExpanded, setIsExpanded] = useState(false);

const { data: notes } = useCommunityNotes({ videoUrl: currentUrl });

const writeNoteLink = (
<a
href={buildFrontendUrl(`/dashboard/notes?create_for_video_url=${currentUrl}`)}
target="_blank"
className="text-sm font-semibold text-primary-700 transition-colors hover:text-primary-900 dark:text-primary-500 dark:hover:text-primary-600"
rel="noreferrer"
>
{t('communityNotes.add')}
</a>
);

if (!notes?.length) {
return (
<Card
title={t('communityNotes.title')}
color="dashed"
compact={compact}
preview={t('communityNotes.none')}
>
{writeNoteLink}
</Card>
);
}

const note = notes[0];
const expandable = note.content.length > 100;

return (
<Card
title={t('communityNotes.title')}
color="dashed"
compact={compact}
preview={strLimit(note.content, 20)}
>
<button
type="button"
onClick={() => setIsExpanded(true)}
className={classNames(
(expandable && !isExpanded) ? 'max-h-[5rem] overflow-hidden cursor-pointer' : 'cursor-default',
'relative text-sm text-left select-text',
)}
>
<p>
{note.content}
{note.sources?.map((source, index) => (
<a
key={source}
href={source}
title={source}
target="_blank"
rel="noopener noreferrer"
className="px-1 font-semibold text-primary-700 transition-colors hover:text-primary-900 dark:text-primary-500 dark:hover:text-primary-600"
>
[
{index}
]
</a>
))}
</p>
<div className="mt-2 flex justify-between">
<a
href={buildFrontendUrl(`/dashboard/notes/review?note_id=${note.id}`)}
target="_blank"
className="font-semibold text-primary-700 transition-colors hover:text-primary-900 dark:text-primary-500 dark:hover:text-primary-600"
rel="noreferrer"
>
{t('communityNotes.rate')}
</a>
{writeNoteLink}
</div>
{(expandable && !isExpanded) && (
<div className="absolute bottom-0 left-0 flex h-20 w-full items-end justify-center bg-gradient-to-t from-white from-25% to-white/0">
<div className="text-center font-semibold text-shadow text-shadow-gray-50">
{t('communityNotes.readMore')}
</div>
</div>
)}
</button>
</Card>
);
}

CommunityNoteNotice.propTypes = {};

export default CommunityNoteNotice;
5 changes: 0 additions & 5 deletions src/hooks/usePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ export function usePage() {
log.debug('---> new channel', channelInfo);
setCurrentChannel(channelInfo);
}

console.log(
document.querySelector('#above-the-fold ytd-channel-name yt-formatted-string a'),
document.querySelector('span[itemprop="name"] link[itemprop="url"]'),
);
}

if (!hasChannel) {
Expand Down
1 change: 1 addition & 0 deletions src/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const REACTIONS_GET_FOR_VIDEO = 'REACTIONS_GET_FOR_VIDEO';
export const REACTIONS_GET_ORIGINAL_VIDEOS = 'REACTIONS_GET_ORIGINAL_VIDEOS';
export const CONTENT_RATINGS_GET = 'CONTENT_RATINGS_GET';
export const VIDEO_ANALYTICS_GET = 'VIDEO_ANALYTICS_GET';
export const COMMUNITY_NOTES_GET = 'COMMUNITY_NOTES_GET';
export const SETTING_UPDATE_VISIBLE = 'SETTING_UPDATE_VISIBLE';
export const OPEN_POPUP = 'OPEN_POPUP';
export const SET_BROWSER_THEME = 'SET_BROWSER_THEME';
Expand Down