mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-31 03:28:49 +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 PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const Popup = require('../../Popup');
|
||||
const { Input } = require('stremio-navigation');
|
||||
const styles = require('./styles');
|
||||
|
||||
const UserMenu = ({ className }) => (
|
||||
<Popup>
|
||||
<Popup.Label>
|
||||
<Input className={classnames(className, styles['user-menu-button'])} 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 style={{ background: 'red', width: 400, height: 300 }}>userpanel</div>
|
||||
</Popup.Menu>
|
||||
</Popup>
|
||||
);
|
||||
const UserMenu = ({ className, email, avatar, logout }) => {
|
||||
const [fullscreen, setFullscreen] = React.useState(document.fullscreenElement instanceof HTMLElement);
|
||||
const toggleFullscreen = React.useCallback(() => {
|
||||
if (fullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
document.documentElement.requestFullscreen();
|
||||
}
|
||||
}, [fullscreen]);
|
||||
const onFullscreenChange = React.useCallback(() => {
|
||||
setFullscreen(document.fullscreenElement instanceof HTMLElement);
|
||||
}, []);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
.user-menu {
|
||||
--user-menu-width: 280px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-menu-button {
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
|
|
@ -19,4 +24,109 @@
|
|||
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