mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 03:22:11 +00:00
UserMenu basic implementation
This commit is contained in:
parent
d39c14b554
commit
0255b93258
5 changed files with 210 additions and 165 deletions
|
|
@ -1,22 +1,109 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
const PropTypes = require('prop-types');
|
||||||
const classnames = require('classnames');
|
const classnames = require('classnames');
|
||||||
const Icon = require('stremio-icons/dom');
|
const Icon = require('stremio-icons/dom');
|
||||||
const Popup = require('../../Popup');
|
const Popup = require('../../Popup');
|
||||||
const { Input } = require('stremio-navigation');
|
const { Input } = require('stremio-navigation');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
const UserMenu = ({ className }) => (
|
const UserMenu = ({ className, email, avatar, logout }) => {
|
||||||
<Popup>
|
const [fullscreen, setFullscreen] = React.useState(document.fullscreenElement instanceof HTMLElement);
|
||||||
<Popup.Label>
|
const toggleFullscreen = React.useCallback(() => {
|
||||||
<Input className={classnames(className, styles['user-menu-button'])} type={'button'}>
|
if (fullscreen) {
|
||||||
<Icon className={classnames(styles['icon'], styles['user-icon'])} icon={'ic_user'} />
|
document.exitFullscreen();
|
||||||
<Icon className={classnames(styles['icon'], styles['arrow-icon'])} icon={'ic_arrow_down'} />
|
} else {
|
||||||
</Input>
|
document.documentElement.requestFullscreen();
|
||||||
</Popup.Label>
|
}
|
||||||
<Popup.Menu>
|
}, [fullscreen]);
|
||||||
<div style={{ background: 'red', width: 400, height: 300 }}>userpanel</div>
|
const onFullscreenChange = React.useCallback(() => {
|
||||||
</Popup.Menu>
|
setFullscreen(document.fullscreenElement instanceof HTMLElement);
|
||||||
</Popup>
|
}, []);
|
||||||
);
|
React.useEffect(() => {
|
||||||
|
document.addEventListener('fullscreenchange', onFullscreenChange);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('fullscreenchange', onFullscreenChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popup modalContainerClassName={styles['user-menu-modal-container']}>
|
||||||
|
<Popup.Label>
|
||||||
|
<Input className={classnames(className, styles['user-menu-button'])} tabIndex={-1} type={'button'}>
|
||||||
|
<Icon className={classnames(styles['icon'], styles['user-icon'])} icon={'ic_user'} />
|
||||||
|
<Icon className={classnames(styles['icon'], styles['arrow-icon'])} icon={'ic_arrow_down'} />
|
||||||
|
</Input>
|
||||||
|
</Popup.Label>
|
||||||
|
<Popup.Menu>
|
||||||
|
<div className={styles['user-menu']}>
|
||||||
|
<div className={styles['user-info']}>
|
||||||
|
<div
|
||||||
|
className={styles['avatar']}
|
||||||
|
style={{
|
||||||
|
backgroundImage: email.length === 0 ?
|
||||||
|
`url('/images/anonymous.png')`
|
||||||
|
:
|
||||||
|
`url('${avatar}'), url('/images/default_avatar.png')`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className={styles['email-container']}>
|
||||||
|
<div className={styles['user-info-label']}>{email.length === 0 ? 'Anonymous user' : email}</div>
|
||||||
|
</div>
|
||||||
|
<Input className={styles['login-logout-button']} tabIndex={-1} type={email.length === 0 ? 'link' : 'button'} href={email.length === 0 ? '#/intro' : null} onClick={email.length === 0 ? null : logout}>
|
||||||
|
<div className={styles['user-info-label']}>{email.length === 0 ? 'Log in / Sign up' : 'Log out'}</div>
|
||||||
|
</Input>
|
||||||
|
</div>
|
||||||
|
<div className={styles['user-menu-section']}>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'button'} onClick={toggleFullscreen}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_fullscreen'} />
|
||||||
|
<div className={styles['option-label']}>{fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}</div>
|
||||||
|
</Input>
|
||||||
|
</div>
|
||||||
|
<div className={styles['user-menu-section']}>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'link'} href={'#/settings'}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_settings'} />
|
||||||
|
<div className={styles['option-label']}>Settings</div>
|
||||||
|
</Input>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'link'} href={'#/addons'}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_addons'} />
|
||||||
|
<div className={styles['option-label']}>Addons</div>
|
||||||
|
</Input>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'button'}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_remote'} />
|
||||||
|
<div className={styles['option-label']}>Remote Control</div>
|
||||||
|
</Input>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'button'}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_magnet'} />
|
||||||
|
<div className={styles['option-label']}>Play Magnet Link</div>
|
||||||
|
</Input>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'link'} href={'https://stremio.zendesk.com/'} target={'_blank'}>
|
||||||
|
<Icon className={styles['option-icon']} icon={'ic_help'} />
|
||||||
|
<div className={styles['option-label']}>Help & Feedback</div>
|
||||||
|
</Input>
|
||||||
|
</div>
|
||||||
|
<div className={styles['user-menu-section']}>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'link'} href={'https://www.stremio.com/tos'} target={'_blank'}>
|
||||||
|
<div className={styles['option-label']}>Terms of Service</div>
|
||||||
|
</Input>
|
||||||
|
<Input className={classnames(styles['option'], 'focusable-with-border')} type={'link'} href={'https://www.stremio.com/'} target={'_blank'}>
|
||||||
|
<div className={styles['option-label']}>About Stremio</div>
|
||||||
|
</Input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Popup.Menu>
|
||||||
|
</Popup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
UserMenu.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
email: PropTypes.string.isRequired,
|
||||||
|
avatar: PropTypes.string.isRequired,
|
||||||
|
logout: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
UserMenu.defaultProps = {
|
||||||
|
email: '',
|
||||||
|
avatar: ''
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = UserMenu;
|
module.exports = UserMenu;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
.user-menu {
|
||||||
|
--user-menu-width: 280px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.user-menu-button {
|
.user-menu-button {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -19,4 +24,109 @@
|
||||||
width: 16%;
|
width: 16%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu-modal-container {
|
||||||
|
--box-shadow: -0.6em .6em .5em -0.1em var(--color-backgrounddark40);
|
||||||
|
|
||||||
|
.user-menu {
|
||||||
|
width: var(--user-menu-width);
|
||||||
|
background-color: var(--color-background);
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: grid;
|
||||||
|
width: 100%;
|
||||||
|
height: 6em;
|
||||||
|
grid-template-columns: 6em 1fr;
|
||||||
|
grid-template-rows: 50% 50%;
|
||||||
|
grid-template-areas:
|
||||||
|
"avatar email"
|
||||||
|
"avatar login-logout-button";
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
grid-area: avatar;
|
||||||
|
padding: 0.8em;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-origin: content-box;
|
||||||
|
background-clip: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-container {
|
||||||
|
grid-area: email;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.8em 0.8em 0 0;
|
||||||
|
color: var(--color-surfacelighter);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-logout-button {
|
||||||
|
grid-area: login-logout-button;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 0.8em 0.8em 0;
|
||||||
|
color: var(--color-surface);
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--color-surfacelighter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-container, .login-logout-button {
|
||||||
|
.user-info-label {
|
||||||
|
flex: 1;
|
||||||
|
max-height: 100%;
|
||||||
|
line-height: 1.1em;
|
||||||
|
word-break: break-all;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-menu-section {
|
||||||
|
width: 100%;
|
||||||
|
border-top: calc(0.5 * var(--focusable-border-size)) solid var(--color-surfacedark80);
|
||||||
|
|
||||||
|
.option {
|
||||||
|
width: 100%;
|
||||||
|
height: 4em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-backgroundlighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-icon {
|
||||||
|
width: 4em;
|
||||||
|
height: 4em;
|
||||||
|
padding: 1.3em;
|
||||||
|
fill: var(--color-secondarylight);
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-label {
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 1.3em;
|
||||||
|
max-height: 2.2em;
|
||||||
|
line-height: 1.1em;
|
||||||
|
color: var(--color-surfacelighter);
|
||||||
|
word-break: break-all;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:only-child {
|
||||||
|
padding-left: 1.3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import Icon from 'stremio-icons/dom';
|
|
||||||
import styles from './styles';
|
|
||||||
|
|
||||||
const renderAvatar = (avatar, email) => {
|
|
||||||
if (email.length === 0) {
|
|
||||||
return (
|
|
||||||
<div style={{ backgroundImage: `url('/images/anonymous.png')` }} className={styles['avatar']} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ backgroundImage: `url('${avatar}'), url('/images/default_avatar.png') ` }} className={styles['avatar']} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderEmail = (email) => {
|
|
||||||
return (
|
|
||||||
<div className={styles['email']}>{email.length === 0 ? 'Anonymous' : email}</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const UserPanel = (props) => {
|
|
||||||
return (
|
|
||||||
<div className={styles['user-panel']}>
|
|
||||||
<div className={styles['user-info']}>
|
|
||||||
{renderAvatar(props.avatar, props.email)}
|
|
||||||
{renderEmail(props.email)}
|
|
||||||
<div onClick={props.email.length === 0 ? props.login : props.logout} className={styles['login-logout']}>{props.email.length === 0 ? 'Log in' : 'Log out'}</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles['separator']}></div>
|
|
||||||
<div onClick={props.resizeWindow} className={styles['option']}>
|
|
||||||
<Icon className={styles['icon']} icon={'ic_fullscreen'} />Fullscreen mode
|
|
||||||
</div>
|
|
||||||
<div className={styles['separator']}></div>
|
|
||||||
<a href={'#settings'} className={styles['option']}>
|
|
||||||
<Icon className={styles['icon']} icon={'ic_settings'} />Settings
|
|
||||||
</a>
|
|
||||||
<a href={'#addons'} className={styles['option']}>
|
|
||||||
<Icon className={styles['icon']} icon={'ic_addons'} />Add-ons
|
|
||||||
</a>
|
|
||||||
<div onClick={props.playMagnetLink} className={styles['option']}>
|
|
||||||
<Icon className={styles['icon']} icon={'ic_magnet'} />Play Magnet Link
|
|
||||||
</div>
|
|
||||||
<a href={'https://stremio.zendesk.com'} target={'_blank'} className={styles['option']}>
|
|
||||||
<Icon className={styles['icon']} icon={'ic_help'} />Help & Feedback
|
|
||||||
</a>
|
|
||||||
<div className={styles['separator']}></div>
|
|
||||||
<a href={'https://www.stremio.com/tos'} target={'_blank'} className={styles['option']}>Terms of Service</a>
|
|
||||||
<a href={'https://www.stremio.com'} target={'_blank'} className={styles['option']}>About Stremio</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserPanel.propTypes = {
|
|
||||||
avatar: PropTypes.string.isRequired,
|
|
||||||
email: PropTypes.string.isRequired,
|
|
||||||
login: PropTypes.func,
|
|
||||||
logout: PropTypes.func,
|
|
||||||
resizeWindow: PropTypes.func,
|
|
||||||
playMagnetLink: PropTypes.func,
|
|
||||||
};
|
|
||||||
UserPanel.defaultProps = {
|
|
||||||
avatar: '',
|
|
||||||
email: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UserPanel;
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
import UserPanel from './UserPanel';
|
|
||||||
|
|
||||||
export default UserPanel;
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
.user-panel {
|
|
||||||
--user-panel-width: 260px;
|
|
||||||
--spacing: 16px;
|
|
||||||
--separator-height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-panel {
|
|
||||||
width: var(--user-panel-width);
|
|
||||||
background-color: var(--color-backgroundlighter);
|
|
||||||
|
|
||||||
.user-info {
|
|
||||||
display: grid;
|
|
||||||
padding: var(--spacing);
|
|
||||||
grid-template-columns: calc(0.2 * var(--user-panel-width)) auto;
|
|
||||||
grid-template-rows: calc(0.1 * var(--user-panel-width)) calc(0.1 * var(--user-panel-width));
|
|
||||||
grid-template-areas:
|
|
||||||
"avatar email"
|
|
||||||
"avatar login-logout";
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
grid-area: avatar;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email {
|
|
||||||
grid-area: email;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--color-surfacelighter);
|
|
||||||
padding-left: var(--spacing);
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: pre;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-logout {
|
|
||||||
grid-area: login-logout;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--color-surface);
|
|
||||||
padding-left: var(--spacing);
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: pre;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--color-surfacelighter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.option {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: var(--spacing);
|
|
||||||
color: var(--color-surfacelighter80);
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: calc(var(--user-panel-width) * 0.08);
|
|
||||||
height: calc(var(--user-panel-width) * 0.08);
|
|
||||||
margin-right: var(--spacing);
|
|
||||||
fill: var(--color-secondarylighter);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--color-surfacelighter);
|
|
||||||
background-color: var(--color-secondarylighter20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.separator {
|
|
||||||
height: var(--separator-height);
|
|
||||||
background-color: var(--color-surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue