mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-20 15:36:03 +00:00
feat: add notification counter on library items
This commit is contained in:
parent
fed8646dc8
commit
a81303e5ef
8 changed files with 94 additions and 1 deletions
|
|
@ -129,6 +129,12 @@ const App = () => {
|
|||
action: 'SyncLibraryWithAPI'
|
||||
}
|
||||
});
|
||||
services.core.transport.dispatch({
|
||||
action: 'Ctx',
|
||||
args: {
|
||||
action: 'PullNotifications'
|
||||
}
|
||||
});
|
||||
};
|
||||
if (services.core.active) {
|
||||
onWindowFocus();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const React = require('react');
|
|||
const { useServices } = require('stremio/services');
|
||||
const PropTypes = require('prop-types');
|
||||
const MetaItem = require('stremio/common/MetaItem');
|
||||
const useNotifications = require('stremio/common/useNotifications');
|
||||
const { t } = require('i18next');
|
||||
|
||||
const OPTIONS = [
|
||||
|
|
@ -15,6 +16,11 @@ const OPTIONS = [
|
|||
|
||||
const LibItem = ({ _id, removable, ...props }) => {
|
||||
const { core } = useServices();
|
||||
const notifications = useNotifications();
|
||||
const newVideos = React.useMemo(() => {
|
||||
const count = notifications.items?.[_id]?.length ?? 0;
|
||||
return Math.min(Math.max(count, 0), 99);
|
||||
}, [_id, notifications.items]);
|
||||
const options = React.useMemo(() => {
|
||||
return OPTIONS
|
||||
.filter(({ value }) => {
|
||||
|
|
@ -91,6 +97,7 @@ const LibItem = ({ _id, removable, ...props }) => {
|
|||
return (
|
||||
<MetaItem
|
||||
{...props}
|
||||
newVideos={newVideos}
|
||||
options={options}
|
||||
optionOnSelect={optionOnSelect}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const useBinaryState = require('stremio/common/useBinaryState');
|
|||
const { ICON_FOR_TYPE } = require('stremio/common/CONSTANTS');
|
||||
const styles = require('./styles');
|
||||
|
||||
const MetaItem = React.memo(({ className, type, name, poster, posterShape, playIcon, progress, options, deepLinks, dataset, optionOnSelect, ...props }) => {
|
||||
const MetaItem = React.memo(({ className, type, name, poster, posterShape, playIcon, progress, newVideos, options, deepLinks, dataset, optionOnSelect, ...props }) => {
|
||||
const [menuOpen, onMenuOpen, onMenuClose] = useBinaryState(false);
|
||||
const href = React.useMemo(() => {
|
||||
return deepLinks ?
|
||||
|
|
@ -89,6 +89,18 @@ const MetaItem = React.memo(({ className, type, name, poster, posterShape, playI
|
|||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
newVideos > 0 ?
|
||||
<div className={styles['new-videos']}>
|
||||
<div className={styles['layer']} />
|
||||
<div className={styles['layer']} />
|
||||
<div className={styles['layer']}>
|
||||
+{newVideos}
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
(typeof name === 'string' && name.length > 0) || (Array.isArray(options) && options.length > 0) ?
|
||||
|
|
@ -129,6 +141,7 @@ MetaItem.propTypes = {
|
|||
posterShape: PropTypes.oneOf(['poster', 'landscape', 'square']),
|
||||
playIcon: PropTypes.bool,
|
||||
progress: PropTypes.number,
|
||||
newVideos: PropTypes.number,
|
||||
options: PropTypes.array,
|
||||
deepLinks: PropTypes.shape({
|
||||
metaDetailsVideos: PropTypes.string,
|
||||
|
|
|
|||
|
|
@ -118,6 +118,45 @@
|
|||
background-color: @color-primaryvariant1;
|
||||
}
|
||||
}
|
||||
|
||||
.new-videos {
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
overflow: visible;
|
||||
|
||||
.layer {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 1.6rem;
|
||||
width: 2.75rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: @color-background-dark2-90;
|
||||
|
||||
&:nth-child(1) {
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
background-color: @color-surface-light5-40;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
top: 0.75rem;
|
||||
right: 0.75rem;
|
||||
background-color: @color-surface-light5-60;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
background-color: @color-surface-light5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title-bar-container {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const useBinaryState = require('./useBinaryState');
|
|||
const useFullscreen = require('./useFullscreen');
|
||||
const useLiveRef = require('./useLiveRef');
|
||||
const useModelState = require('./useModelState');
|
||||
const useNotifications = require('./useNotifications');
|
||||
const useOnScrollToBottom = require('./useOnScrollToBottom');
|
||||
const useProfile = require('./useProfile');
|
||||
const useStreamingServer = require('./useStreamingServer');
|
||||
|
|
@ -83,6 +84,7 @@ module.exports = {
|
|||
useFullscreen,
|
||||
useLiveRef,
|
||||
useModelState,
|
||||
useNotifications,
|
||||
useOnScrollToBottom,
|
||||
useProfile,
|
||||
useStreamingServer,
|
||||
|
|
|
|||
2
src/common/useNotifications.d.ts
vendored
Normal file
2
src/common/useNotifications.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
declare const useNotifcations: () => Notifications;
|
||||
export = useNotifcations;
|
||||
11
src/common/useNotifications.js
Normal file
11
src/common/useNotifications.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
const useModelState = require('stremio/common/useModelState');
|
||||
|
||||
const map = (ctx) => ctx.notifications;
|
||||
|
||||
const useNotifications = () => {
|
||||
return useModelState({ model: 'ctx', map });
|
||||
};
|
||||
|
||||
module.exports = useNotifications;
|
||||
13
src/types/models/Ctx.d.ts
vendored
13
src/types/models/Ctx.d.ts
vendored
|
|
@ -42,6 +42,19 @@ type Profile = {
|
|||
settings: Settings,
|
||||
};
|
||||
|
||||
type VideoNotification = {
|
||||
meta_id: string,
|
||||
video_id: string,
|
||||
video: Video,
|
||||
};
|
||||
|
||||
type Notifications = {
|
||||
uid: string,
|
||||
created: string,
|
||||
items: Record<string, VideoNotification[]>,
|
||||
};
|
||||
|
||||
type Ctx = {
|
||||
profile: Profile,
|
||||
notifications: Notifications,
|
||||
};
|
||||
Loading…
Reference in a new issue