1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

proof of concept

This commit is contained in:
David Murdoch 2024-12-11 15:59:54 -05:00
parent 8ef78024b2
commit e24fffd84b
6 changed files with 59 additions and 8 deletions

View file

@ -45,6 +45,11 @@ const AppUserMenu: FC<AppUserMenuProps> = ({
onMenuClose();
}, [ onMenuClose ]);
const onSwitchUserClick = useCallback(() => {
Dashboard.navigate('login.html')
onMenuClose();
}, [ onMenuClose ]);
const onLogoutClick = useCallback(() => {
Dashboard.logout();
onMenuClose();
@ -168,6 +173,17 @@ const AppUserMenu: FC<AppUserMenuProps> = ({
</MenuItem>
)}
<MenuItem
onClick={onSwitchUserClick}
>
<ListItemIcon>
<Logout />
</ListItemIcon>
<ListItemText>
{globalize.translate('SwitchUser')}
</ListItemText>
</MenuItem>
<MenuItem
onClick={onLogoutClick}
>

View file

@ -33,6 +33,11 @@
<div id="divUsers" class="itemsContainer vertical-wrap centered"></div>
</div>
<div class="visualLoginForm" style="text-align: center;">
<h1 style="margin-top:1em;">${HeaderWhosWatching}</h1>
<div id="divSignedInUsers" class="itemsContainer vertical-wrap centered"></div>
</div>
<div class="readOnlyContent" style="margin: .5em auto 1em;">
<button is="emby-button" type="button" class="raised cancel block btnManual">
<span>${ButtonManualLogin}</span>

View file

@ -26,6 +26,12 @@ function authenticateUserByName(page, apiClient, url, username, password) {
const user = result.User;
loading.hide();
// store this user/access token in local storage
// TODO: make this not suck so much
let users = JSON.parse(localStorage.getItem('users')) || [];
users = users.concat({PrimaryImageTag: user.PrimaryImageTag, HasPassword: user.HasPassword, Name: user.Name, Id: user.Id, AccessToken: result.AccessToken});
localStorage.setItem('users', JSON.stringify(users))
onLoginSuccessful(user.Id, result.AccessToken, apiClient, url);
}, function (response) {
page.querySelector('#txtManualPassword').value = '';
@ -132,7 +138,7 @@ function showManualForm(context, showCancel, focusPassword) {
}
}
function loadUserList(context, apiClient, users) {
function loadUserList(context, apiClient, users, target) {
let html = '';
for (const user of users) {
@ -152,7 +158,7 @@ function loadUserList(context, apiClient, users) {
html += '<div class="' + cardBoxCssClass + '">';
html += '<div class="cardScalable">';
html += '<div class="cardPadder cardPadder-square"></div>';
html += `<div class="cardContent" data-haspw="${user.HasPassword}" data-username="${user.Name}" data-userid="${user.Id}">`;
html += `<div class="cardContent" data-accesstoken="${user.AccessToken}" data-haspw="${user.HasPassword}" data-username="${user.Name}" data-userid="${user.Id}">`;
let imgUrl;
if (user.PrimaryImageTag) {
@ -178,7 +184,7 @@ function loadUserList(context, apiClient, users) {
html += '</button>';
}
context.querySelector('#divUsers').innerHTML = html;
target.innerHTML = html;
}
export default function (view, params) {
@ -214,7 +220,7 @@ export default function (view, params) {
});
}
view.querySelector('#divUsers').addEventListener('click', function (e) {
view.querySelectorAll('#divUsers,#divSignedInUsers').forEach(el => el.addEventListener('click', function (e) {
const card = dom.parentWithClass(e.target, 'card');
const cardContent = card ? card.querySelector('.cardContent') : null;
@ -223,8 +229,12 @@ export default function (view, params) {
const id = cardContent.getAttribute('data-userid');
const name = cardContent.getAttribute('data-username');
const haspw = cardContent.getAttribute('data-haspw');
if (id === 'manual') {
const accessToken = cardContent.getAttribute('data-accesstoken');
// if the clicked card has an accessToken attached we can just log
// in right away...
if (accessToken) {
onLoginSuccessful(id, accessToken, getApiClient(), getTargetUrl());
} else if (id === 'manual') {
context.querySelector('#txtManualName').value = '';
showManualForm(context, true);
} else if (haspw == 'false') {
@ -235,7 +245,7 @@ export default function (view, params) {
showManualForm(context, true, true);
}
}
});
}));
view.querySelector('.manualLoginForm').addEventListener('submit', function (e) {
appSettings.enableAutoLogin(view.querySelector('.chkRememberLogin').checked);
authenticateUserByName(view, getApiClient(), getTargetUrl(), view.querySelector('#txtManualName').value, view.querySelector('#txtManualPassword').value);
@ -278,10 +288,16 @@ export default function (view, params) {
console.debug('Failed to get QuickConnect status');
});
// TODO: this shouldn't suck
const loggedInUsers = JSON.parse(window.localStorage.getItem('users') || "[]");
if (loggedInUsers && loggedInUsers.length) {
loadUserList(view, apiClient, loggedInUsers, view.querySelector('#divSignedInUsers'));
}
apiClient.getPublicUsers().then(function (users) {
if (users.length) {
showVisualForm();
loadUserList(view, apiClient, users);
loadUserList(view, apiClient, users, context.querySelector('#divUsers'));
} else {
view.querySelector('#txtManualName').value = '';
showManualForm(view, false, false);

View file

@ -104,6 +104,14 @@
</div>
</div>
</a>
<a is="emby-linkbutton" data-ripple="false" href="#" style="display:block;padding:0;margin:0;" class="btnSwitchUser listItem-border">
<div class="listItem">
<span class="material-icons listItemIcon listItemIcon-transparent exit_to_app" aria-hidden="true"></span>
<div class="listItemBody">
<div class="listItemBodyText">${SwitchUser}</div>
</div>
</div>
</a>
<a is="emby-linkbutton" data-ripple="false" href="#" style="display:block;padding:0;margin:0;" class="btnLogout listItem-border">
<div class="listItem">
<span class="material-icons listItemIcon listItemIcon-transparent exit_to_app" aria-hidden="true"></span>

View file

@ -9,6 +9,10 @@ export default function (view, params) {
Dashboard.logout();
});
view.querySelector('.btnSwitchUser').addEventListener('click', function () {
Dashboard.navigate("login.html");
});
view.querySelector('.selectServer').addEventListener('click', function () {
Dashboard.selectServer();
});

View file

@ -131,6 +131,7 @@
"ButtonShutdown": "Shutdown",
"ButtonSignIn": "Sign In",
"ButtonSignOut": "Sign Out",
"ButtonSwitchUser": "Switch User",
"ButtonExitApp": "Exit Application",
"ButtonSpace": "Space",
"ButtonSplit": "Split",
@ -476,6 +477,7 @@
"HeaderPlaybackError": "Playback Error",
"HeaderPlayOn": "Play On",
"HeaderPleaseSignIn": "Please sign in",
"HeaderWhosWatching": "Who's Watching",
"HeaderPortRanges": "Firewall and Proxy Settings",
"HeaderPreferredMetadataLanguage": "Preferred Metadata Language",
"HeaderPreviewLyrics": "Preview Lyrics",