Skip to content

Commit

Permalink
Login netease (listen1#511)
Browse files Browse the repository at this point in the history
* feat: netease login page and basic login api

* feat: add recommend playlist and i18n

* feat: valid login form before submit

* fix: not initial when login

* style: fix input background/font in night mode

* feat: support phone login

* fix: remove extra console.log

* refactor: move auth related to auth controller
  • Loading branch information
listen1 authored Mar 26, 2021
1 parent 2b408b8 commit fa28a22
Show file tree
Hide file tree
Showing 10 changed files with 1,976 additions and 1,352 deletions.
100 changes: 98 additions & 2 deletions css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ svg {
height: 49px;
border: 5px solid rgba(0, 0, 0, 0);
background-clip: padding-box;
border-radius: 7px;
-webkit-border-radius: 7px;
background-color: var(--scroll-color);
/*rgba(151, 151, 151, 0.4);*/
Expand Down Expand Up @@ -231,6 +232,9 @@ svg {
height: 18px;
color: var(--icon-default-color);
}
.navigation .icon svg {
color: var(--text-default-color);
}
.navigation .backfront {
flex: 0 0 45px;
line-height: 46px;
Expand Down Expand Up @@ -788,6 +792,99 @@ ul.detail-songlist li .tools .icon {
}
/* page song detail end */

/* page login start */
.page .login {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: calc(100vh - 192px);
}
.page .login .login-logo {
margin-bottom: 16px;
display: flex;
align-items: center;
}
.page .login .login-logo img {
height: 64px;
margin: 20px;
}
.page .login .login-title {
font-size: 18px;
margin-bottom: 10px;
}
.page .login .login-form .login-form_field {
display: flex;
align-items: center;
height: 40px;
margin: 24px;
width: 270px;
border: solid 1px var(--button-background-color);
}
.page .login .login-form .login-form_field input {
background: var(--content-background-color);
color: var(--text-default-color);
}
.page .login .login-form .login-form_field input.login-form_field_countrycode {
flex: 0 0 40px;
width: 40px;
}
.page .login .login-form .login-form_field svg {
margin-left: 12px;
margin-right: 12px;
color: var(--icon-default-color);
width: 18px;
height: 18px;
}
.page .login .login-form .login-form_field input {
border: none;
flex: 1;
font-size: 16px;
}
.page .login .login-submit_button {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
margin-top: 24px;
padding: 8px;
width: 270px;
cursor: pointer;
border: solid 1px var(--button-border-color);
}
.page .login .login-switcher {
margin-top: 24px;
cursor: pointer;
}
.page .login .login-notice {
width: 270px;
border-top: 1px solid var(--button-border-color);
margin-top: 30px;
padding-top: 12px;
font-size: 12px;
color: var(--text-subtitle-color);
}
.page .login .usercard {
display: flex;
align-items: center;
width: 300px;
border: solid 1px var(--button-border-color);
}
.page .login .usercard img {
width: 60px;
margin: 10px;
}
.page .login .usercard .usercard-title {
flex: 1;
height: 50px;
font-size: 16px;
font-weight: 700;
}
.page .login .usercard button {
margin: 10px;
}
/* page login end */

/* page setting start */
.page .settings-title {
border-bottom: solid 1px var(--line-default-color);
Expand Down Expand Up @@ -1428,7 +1525,7 @@ svg.searchspinner {

/* widget source-list start */
.source-list {
margin: 20px 26px 0 26px;
margin: 20px 26px 10px 26px;
}

.source-list .source-button {
Expand Down Expand Up @@ -1466,7 +1563,6 @@ svg.searchspinner {
.playlist-filter .filter-item {
padding: 5px 15px;
margin-right: 10px;
margin-top: 10px;
}

.playlist-filter .filter-item.active {
Expand Down
18 changes: 17 additions & 1 deletion i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,21 @@
"_CLOSE_TAB_ACTION": "Close tab action",
"_VALID_AFTER_RESTART": "Valid after restart",
"_QUIT_APPLICATION": "Quit Application",
"_MINIMIZE_TO_BACKGROUND": "Minimize to background"
"_MINIMIZE_TO_BACKGROUND": "Minimize to background",
"_MY_PLAYLIST": "My Playlist",
"_RECOMMEND_PLAYLIST": "Recommend Playlist",
"_LISTEN1_LOGIN_NOTICE": "Listen1 WILL NOT transfer your account data to any server other than music platform server.",
"_PASSWORD": "Password",
"_LOGIN": "Login",
"_LOGOUT": "Logout",
"_LOGIN_ERROR": "Login error, please check user name and password",
"_LOGIN_EMAIL_ERROR": "Please enter correct email address",
"_LOGIN_COUNTRYCODE_ERROR": "Please enter correct country code",
"_LOGIN_PHONE_ERROR": "Please enter correct phone number",
"_LOGIN_PASSWORD_ERROR": "Password can't be empty",
"_LOGIN_NETEASE": "Login Netease",
"_LOGIN_BY_MOBILE_PHONE": "Login by mobile phone",
"_LOGIN_BY_EMAIL": "Login by email",
"_MOBILE_PHONE": "Mobile Phone",
"_MY_NETEASE": "My Netease"
}
18 changes: 17 additions & 1 deletion i18n/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,21 @@
"_CLOSE_TAB_ACTION": "Close tab action",
"_VALID_AFTER_RESTART": "Valid after restart",
"_QUIT_APPLICATION": "Quit Application",
"_MINIMIZE_TO_BACKGROUND": "Minimize to background"
"_MINIMIZE_TO_BACKGROUND": "Minimize to background",
"_MY_PLAYLIST": "My Playlist",
"_RECOMMEND_PLAYLIST": "Recommend Playlist",
"_LISTEN1_LOGIN_NOTICE": "Listen1 NE transférera PAS les données de votre compte vers un serveur autre que le serveur de la plate-forme musicale.",
"_PASSWORD": "Password",
"_LOGIN": "Login",
"_LOGOUT": "Logout",
"_LOGIN_ERROR": "Login error, please check user name and password",
"_LOGIN_EMAIL_ERROR": "Please enter correct email address",
"_LOGIN_COUNTRYCODE_ERROR": "Please enter correct country code",
"_LOGIN_PHONE_ERROR": "Please enter correct phone number",
"_LOGIN_PASSWORD_ERROR": "Password can't be empty",
"_LOGIN_NETEASE": "Login Netease",
"_LOGIN_BY_MOBILE_PHONE": "Login by mobile phone",
"_LOGIN_BY_EMAIL": "Login by email",
"_MOBILE_PHONE": "Mobile Phone",
"_MY_NETEASE": "My Netease"
}
18 changes: 17 additions & 1 deletion i18n/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,21 @@
"_CLOSE_TAB_ACTION": "关闭标签页时行为",
"_VALID_AFTER_RESTART": "需重启生效",
"_QUIT_APPLICATION": "退出应用",
"_MINIMIZE_TO_BACKGROUND": "最小化到后台"
"_MINIMIZE_TO_BACKGROUND": "最小化到后台",
"_MY_PLAYLIST": "我的歌单",
"_RECOMMEND_PLAYLIST": "推荐歌单",
"_LISTEN1_LOGIN_NOTICE": "Listen1不会传输你的账号数据到任何非音乐平台官方的服务器。",
"_PASSWORD": "密码",
"_LOGIN": "登录",
"_LOGOUT": "退出登录",
"_LOGIN_ERROR": "登录失败,请检查用户名和密码",
"_LOGIN_EMAIL_ERROR": "请输入正确的邮箱地址",
"_LOGIN_COUNTRYCODE_ERROR": "请输入正确的国家或地区代码",
"_LOGIN_PHONE_ERROR": "请输入正确的手机号",
"_LOGIN_PASSWORD_ERROR": "密码不能为空",
"_LOGIN_NETEASE": "登录网易云音乐",
"_LOGIN_BY_MOBILE_PHONE": "手机号登录",
"_LOGIN_BY_EMAIL": "邮箱登录",
"_MOBILE_PHONE": "手机号",
"_MY_NETEASE": "我的网易云音乐"
}
18 changes: 17 additions & 1 deletion i18n/zh_TC.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,21 @@
"_CLOSE_TAB_ACTION": "關閉標籤頁時行為",
"_VALID_AFTER_RESTART": "需重載生效",
"_QUIT_APPLICATION": "退出軟體",
"_MINIMIZE_TO_BACKGROUND": "最小化到後臺"
"_MINIMIZE_TO_BACKGROUND": "最小化到後臺",
"_MY_PLAYLIST": "我的歌單",
"_RECOMMEND_PLAYLIST": "推薦歌單",
"_LISTEN1_LOGIN_NOTICE": "Listen1不會傳輸你的賬號數據到任何非音樂平台官方的伺服器。",
"_PASSWORD": "密碼",
"_LOGIN": "登錄",
"_LOGOUT": "退出登錄",
"_LOGIN_ERROR": "登錄失敗,請檢查用戶名和密碼",
"_LOGIN_EMAIL_ERROR": "請輸入正確的郵箱地址",
"_LOGIN_COUNTRYCODE_ERROR": "請輸入正確的國家或地區代碼",
"_LOGIN_PHONE_ERROR": "請輸入正確的手機號",
"_LOGIN_PASSWORD_ERROR": "密碼不能為空",
"_LOGIN_NETEASE": "登錄網易雲音樂",
"_LOGIN_BY_MOBILE_PHONE": "手機號登錄",
"_LOGIN_BY_EMAIL": "郵箱登錄",
"_MOBILE_PHONE": "手機號",
"_MY_NETEASE": "我的網易雲音樂"
}
Binary file added images/netease-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
156 changes: 156 additions & 0 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,114 @@ const main = () => {
},
]);

app.controller('AuthController', [
'$scope',
'$translate',
($scope, $translate) => {
$scope.loginProgress = false;
$scope.loginType = 'email';

$scope.setLoginType = (newType) => {
$scope.loginType = newType;
if (newType === 'phone') {
document.getElementById('login-countrycode').value = '+86';
}
};
// valid email/password
function validateEmail(email_str) {
const re = /\S+@\S+\.\S+/;
return re.test(email_str);
}
function validatePhone(phone_str) {
const re = /^[0-9]{7,16}$/;
return re.test(phone_str);
}
function validateCountrycode(countrycode_str) {
const re = /^\+[0-9]{1,4}$/;
return re.test(countrycode_str);
}
function validatePassword(password_str) {
return password_str !== '';
}
$scope.login = (source) => {
let options = {};
if ($scope.loginType === 'email') {
const email = document.getElementById('login-email').value;
const password = document.getElementById('login-password').value;

if (!validateEmail(email)) {
return Notification.warning(
$translate.instant('_LOGIN_EMAIL_ERROR')
);
}
if (!validatePassword(password)) {
return Notification.warning(
$translate.instant('_LOGIN_PASSWORD_ERROR')
);
}
options = {
type: $scope.loginType,
email,
password,
};
} else if ($scope.loginType === 'phone') {
const countrycode = document.getElementById('login-countrycode')
.value;

const phone = document.getElementById('login-phone').value;
const password = document.getElementById('login-password').value;
if (!validateCountrycode(countrycode)) {
return Notification.warning(
$translate.instant('_LOGIN_COUNTRYCODE_ERROR')
);
}
if (!validatePhone(phone)) {
return Notification.warning(
$translate.instant('_LOGIN_PHONE_ERROR')
);
}
if (!validatePassword(password)) {
return Notification.warning(
$translate.instant('_LOGIN_PASSWORD_ERROR')
);
}
options = {
type: $scope.loginType,
phone,
countrycode: countrycode.slice(1),
password,
};
} else {
return Notification.error('not support login type');
}
$scope.loginProgress = true;
return MediaService.login(source, options).success((data) => {
$scope.loginProgress = false;
if (data.status === 'success') {
$scope.setMusicAuth(source, data.data);
} else {
Notification.error($translate.instant('_LOGIN_ERROR'));
}
});
};

$scope.logout = (source) => {
$scope.setMusicAuth(source, {});
// TODO: clear cookie
};

$scope.is_login = (source) =>
$scope.musicAuth[source] && $scope.musicAuth[source].is_login;

$scope.musicAuth = localStorage.getObject('music_auth') || {};

$scope.setMusicAuth = (source, data) => {
$scope.musicAuth[source] = data;
localStorage.setObject('music_auth', $scope.musicAuth);
};
},
]);

// control main view of page, it can be called any place
app.controller('NavigationController', [
'$scope',
Expand Down Expand Up @@ -2003,6 +2111,54 @@ const main = () => {
},
]);

const platformSourceList = [
{
name: 'my_playlist',
displayId: '_MY_PLAYLIST',
},
{
name: 'recommend_playlist',
displayId: '_RECOMMEND_PLAYLIST',
},
];

app.controller('PlatformController', [
'$scope',
($scope) => {
$scope.myPlatformPlaylists = [];
$scope.myPlatformUser = {};
$scope.platformSourceList = platformSourceList;
$scope.tab = platformSourceList[0].name;

$scope.loadPlatformPlaylists = () => {
if ($scope.myPlatformUser.platform === undefined) {
return;
}
let getPlaylistFn = MediaService.getUserPlaylist;
if ($scope.tab === 'recommend_playlist') {
getPlaylistFn = MediaService.getRecommendPlaylist;
}
const user = $scope.myPlatformUser;
getPlaylistFn(user.platform, {
user_id: user.user_id,
}).success((response) => {
const { data } = response;
$scope.myPlatformPlaylists = data.playlists;
});
};

$scope.initPlatformController = (user) => {
$scope.myPlatformUser = user;
$scope.loadPlatformPlaylists();
};

$scope.changePlatformTab = (name) => {
$scope.tab = name;
$scope.loadPlatformPlaylists();
};
},
]);

app.controller('PlayListController', [
'$scope',
'$timeout',
Expand Down
Loading

0 comments on commit fa28a22

Please sign in to comment.