Change "Default" profile to "All Channels" and other small changes

This commit is contained in:
PrestonN 2019-08-01 14:42:36 -04:00
parent 7bb97d3aca
commit 62b956f1b4
10 changed files with 195 additions and 110 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -85,6 +85,10 @@ function goToChannel(channelId) {
data.latestVideos.forEach((video) => { data.latestVideos.forEach((video) => {
displayVideo(video, 'channel'); displayVideo(video, 'channel');
}); });
if (typeof(channelView.banner) === 'undefined') {
window.setTimeout(() => {$('.channelViewBanner').get(0).height = 200;}, 50);
}
}, (errorData) => { }, (errorData) => {
showToast(errorData.responseJSON.error); showToast(errorData.responseJSON.error);
loadingView.seen = false; loadingView.seen = false;

View File

@ -68,8 +68,6 @@ let init = function () {
//let winHeight = 800; //let winHeight = 800;
win = new BrowserWindow({ win = new BrowserWindow({
width: 1200,
height: 800,
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
@ -77,25 +75,7 @@ let init = function () {
icon: path.join(__dirname, '..', 'icons', 'iconColor.png') icon: path.join(__dirname, '..', 'icons', 'iconColor.png')
}); });
settingsDb.findOne({ win.setBounds({width: 1200, height: 800});
_id: 'bounds'
}, function (err, doc) {
if (typeof doc !== "object" || typeof doc.value !== "object") {
return;
}
const {maximized, ...bounds} = doc.value;
const allDisplaysSummaryWidth = screen
.getAllDisplays()
.reduce((accumulator, {size: {width}}) => accumulator + width, 0);
if (allDisplaysSummaryWidth >= bounds.x) {
win.setBounds(bounds);
}
if (maximized) {
win.maximize();
}
});
settingsDb.findOne({ settingsDb.findOne({
_id: 'useTor' _id: 'useTor'
@ -132,7 +112,7 @@ let init = function () {
}); });
if (process.env = 'development') { if (process.env = 'development') {
//win.webContents.openDevTools(); win.webContents.openDevTools();
} }
win.on('closed', () => { win.on('closed', () => {
@ -225,6 +205,30 @@ let init = function () {
const menu = Menu.buildFromTemplate(template); const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu); Menu.setApplicationMenu(menu);
settingsDb.findOne({
_id: 'bounds'
}, function (err, doc) {
if (doc === null) {
return;
}
if (typeof doc !== "object" || typeof doc.value !== "object") {
return;
}
const {maximized, ...bounds} = doc.value;
const allDisplaysSummaryWidth = screen
.getAllDisplays()
.reduce((accumulator, {size: {width}}) => accumulator + width, 0);
if (allDisplaysSummaryWidth >= bounds.x) {
win.setBounds({"x":bounds.x,"y":bounds.y,"width":bounds.width,"height":bounds.height});
}
if (maximized) {
win.maximize();
}
});
/** /**
* Sets proxy when setProxy event is sent from renderer * Sets proxy when setProxy event is sent from renderer
* *

View File

@ -180,11 +180,13 @@ function checkDefaultSettings() {
'distractionFreeMode': false, 'distractionFreeMode': false,
'hideWatchedSubs': false, 'hideWatchedSubs': false,
'videoView': 'grid', 'videoView': 'grid',
'profileList': [{ 'profileList': [
name: 'Default', {
name: 'All Channels',
color: randomColor color: randomColor
}, ], },
'defaultProfile': 'Default', ],
'defaultProfile': 'All Channels',
}; };
ft.log(settingDefaults); ft.log(settingDefaults);
@ -221,7 +223,7 @@ function checkDefaultSettings() {
}, { }, {
$set: { $set: {
profile: [{ profile: [{
value: 'Default' value: 'All Channels'
}] }]
} }
}, {}, (err, newDoc) => { }, {}, (err, newDoc) => {
@ -856,7 +858,7 @@ function importSubscriptions() {
let colorPaletteKeys = Object.keys(colorPalette); let colorPaletteKeys = Object.keys(colorPalette);
let randomColor = colorPalette[colorPaletteKeys[colorPaletteKeys.length * Math.random() << 0]]; let randomColor = colorPalette[colorPaletteKeys[colorPaletteKeys.length * Math.random() << 0]];
editProfileView.isNewProfile = true; editProfileView.isNewProfile = true;
editProfileView.newProfileColor = randomColor; editProfileView.newProfileColorText = randomColor;
editProfileView.newProfileName = profile.value; editProfileView.newProfileName = profile.value;
editProfileView.updateProfile(false); editProfileView.updateProfile(false);
} }

View File

@ -84,23 +84,25 @@ function addSubscription(data, useToast = true, profile = '') {
* *
* @return {Void} * @return {Void}
*/ */
function removeSubscription(channelId) { function removeSubscription(channelId, profile = profileSelectView.activeProfile.name, displayToast = true) {
subDb.find({ subDb.find({
channelId: channelId channelId: channelId
}, (err, docs) => { }, (err, docs) => {
if (docs[0].profile.length > 1) { if (docs[0].profile.length > 1 && profile !== 'All Profiles') {
subDb.update({ subDb.update({
channelId: channelId, channelId: channelId,
}, { }, {
$pull: { $pull: {
profile: { profile: {
value: profileSelectView.activeProfile.name value: profile
} }
} }
}, (err, numAdded) => { }, { multi: true },(err, numRemoved) => {
// Refresh the list of subscriptions on the side navigation bar. // Refresh the list of subscriptions on the side navigation bar.
displaySubs(); displaySubs();
showToast('Removed channel from subscriptions.'); if (displayToast) {
showToast('Removed channel from subscriptions.');
}
}); });
} else { } else {
subDb.remove({ subDb.remove({
@ -108,7 +110,9 @@ function removeSubscription(channelId) {
}, {}, (err, numRemoved) => { }, {}, (err, numRemoved) => {
// Refresh the list of subscriptions on the side navigation bar. // Refresh the list of subscriptions on the side navigation bar.
displaySubs(); displaySubs();
showToast('Removed channel from subscriptions.'); if (displayToast) {
showToast('Removed channel from subscriptions.');
}
}); });
} }
}); });
@ -198,9 +202,11 @@ function addSubsToView(videoList) {
}); });
} }
videoList = videoList.filter(a => { if (profileSelectView.activeProfile.name !== 'All Channels') {
videoList = videoList.filter(a => {
return a.profile.map(x => x.value).indexOf(profileSelectView.activeProfile.name) !== -1 return a.profile.map(x => x.value).indexOf(profileSelectView.activeProfile.name) !== -1
}); });
}
videoList.sort((a, b) => { videoList.sort((a, b) => {
return b.published - a.published; return b.published - a.published;
@ -278,16 +284,20 @@ function displaySubs() {
subList.innerHTML = ''; subList.innerHTML = '';
// Sort alphabetically // Sort alphabetically
subDb.find({ subDb.find().sort({
profile: {
$elemMatch: {
value: profileSelectView.activeProfile.name
}
}
}).sort({
channelName: 1 channelName: 1
}).exec((err, subs) => { }).exec((err, subs) => {
subs.forEach((channel) => { let subFilter;
if (profileSelectView.activeProfile.name === 'All Channels' || typeof(profileSelectView.activeProfile.name) === 'undefined') {
subFilter = subs;
}
else {
subFilter = subs.filter(a => {
return a.profile.find((name) => {return name.value === profileSelectView.activeProfile.name });
});
}
subFilter.forEach((channel) => {
// Grab subscriptions.html to be used as a template. // Grab subscriptions.html to be used as a template.
const subsTemplate = require('./templates/subscriptions.html') const subsTemplate = require('./templates/subscriptions.html')
mustache.parse(subsTemplate); mustache.parse(subsTemplate);

View File

@ -923,15 +923,32 @@ let subscriptionManagerView = new Vue({
if (isNewProfile) { if (isNewProfile) {
editProfileView.profileName = ''; editProfileView.profileName = '';
editProfileView.profileColor = ''; editProfileView.profileColor = '';
editProfileView.newProfileName = ''; editProfileView.newProfileName = 'Profile ' + (this.profileList.length + 1);
editProfileView.newProfileColor = ''; let colorPaletteKeys = Object.keys(editProfileView.colorPalette);
let randomColor = colorPalette[colorPaletteKeys[colorPaletteKeys.length * Math.random() << 0]];
editProfileView.newProfileColorText = randomColor;
editProfileView.subscriptionList = []; editProfileView.subscriptionList = [];
} else { } else {
editProfileView.profileName = this.profileList[index].name; editProfileView.profileName = this.profileList[index].name;
editProfileView.profileColor = this.profileList[index].color; editProfileView.profileColor = this.profileList[index].color;
editProfileView.newProfileName = this.profileList[index].name; editProfileView.newProfileName = this.profileList[index].name;
editProfileView.newProfileColor = this.profileList[index].color; editProfileView.newProfileColorText = this.profileList[index].color;
// Sort alphabetically if (this.profileList[index].name === 'All Channels') {
// Sort alphabetically
subDb.find({
}).sort({
channelName: 1
}).exec((err, subs) => {
let list = [];
subs.forEach((sub) => {
sub.checked = false;
list.push(sub);
});
editProfileView.subscriptionList = list;
});
}
else {
// Sort alphabetically
subDb.find({ subDb.find({
profile: { profile: {
$elemMatch: { $elemMatch: {
@ -948,8 +965,10 @@ let subscriptionManagerView = new Vue({
}); });
editProfileView.subscriptionList = list; editProfileView.subscriptionList = list;
}); });
}
} }
editProfileView.seen = true; editProfileView.seen = true;
loadingView.seen = false;
//backButtonView.lastView = subscriptionManagerView; //backButtonView.lastView = subscriptionManagerView;
} }
}, },
@ -976,7 +995,7 @@ let editProfileView = new Vue({
profileName: '', profileName: '',
profileColor: '', profileColor: '',
newProfileName: '', newProfileName: '',
newProfileColor: '', newProfileColorText: '',
selectedProfile: '', selectedProfile: '',
colorPalette: { colorPalette: {
red: '#d50000', red: '#d50000',
@ -999,7 +1018,7 @@ let editProfileView = new Vue({
}, },
methods: { methods: {
changeProfileColor: function (value) { changeProfileColor: function (value) {
this.newProfileColor = value; this.newProfileColorText = value;
}, },
selectAll: function () { selectAll: function () {
this.subscriptionList.forEach(channel => { this.subscriptionList.forEach(channel => {
@ -1012,6 +1031,11 @@ let editProfileView = new Vue({
}); });
}, },
defaultProfile: function () { defaultProfile: function () {
if (editProfileView.profileName === settingsView.defaultProfile) {
showToast('This profile is already set as your default.');
return;
}
settingsDb.update({ settingsDb.update({
_id: 'defaultProfile' _id: 'defaultProfile'
}, { }, {
@ -1087,6 +1111,11 @@ let editProfileView = new Vue({
}); });
}, },
updateProfile: function (updateView = true) { updateProfile: function (updateView = true) {
if (this.newProfileName === '') {
showToast('Profile name cannot be blank.');
return;
}
let patt = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"); let patt = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
if (patt.test(this.newProfileColor)) { if (patt.test(this.newProfileColor)) {
if (this.isNewProfile) { if (this.isNewProfile) {
@ -1121,7 +1150,7 @@ let editProfileView = new Vue({
if (updateView) { if (updateView) {
hideViews(); hideViews();
subscriptionManagerView.seen = true; subscriptionManagerView.seen = true;
showToast('The' + newProfile.name + ' profile has been added!'); showToast('The ' + newProfile.name + ' profile has been added!');
} }
}); });
} }
@ -1244,7 +1273,11 @@ let editProfileView = new Vue({
showToast('Select a profile other than the one being edited.'); showToast('Select a profile other than the one being edited.');
return; return;
} }
let confirmString = 'Would you like to move the selected channels to the ' + this.selectedProfile + ' profile?'; if (this.selectedProfile === 'All Channels') {
showToast('There is no need to move channels to "All Channels".');
return;
}
let confirmString = 'Would you like to move the selected channel(s) to the ' + this.selectedProfile + ' profile?';
confirmFunction(confirmString, () => { confirmFunction(confirmString, () => {
let amountRemoved = 0; let amountRemoved = 0;
this.subscriptionList.forEach(channel => { this.subscriptionList.forEach(channel => {
@ -1318,7 +1351,11 @@ let editProfileView = new Vue({
showToast('Select a profile other than the one being edited.'); showToast('Select a profile other than the one being edited.');
return; return;
} }
let confirmString = 'Would you like to copy the selected channels to the ' + this.selectedProfile + ' profile?'; if (this.selectedProfile === 'All Channels') {
showToast('There is no need to copy channels to "All Channels".');
return;
}
let confirmString = 'Would you like to copy the selected channel(s) to the ' + this.selectedProfile + ' profile?';
confirmFunction(confirmString, () => { confirmFunction(confirmString, () => {
let amountCopied = 0; let amountCopied = 0;
this.subscriptionList.forEach(channel => { this.subscriptionList.forEach(channel => {
@ -1369,52 +1406,55 @@ let editProfileView = new Vue({
}); });
}, },
deleteChannel: function () { deleteChannel: function () {
let confirmString = 'Are you sure you want to delete the selected channels from this profile?'; let confirmString = 'Are you sure you want to delete the selected channel(s) from this profile?';
let amountDeleted = 0; let amountDeleted = 0;
if (this.amountSelected === 0) {
showToast('A channel must be selected before it can be deleted.');
return;
}
confirmFunction(confirmString, () => { confirmFunction(confirmString, () => {
this.subscriptionList.forEach((channel, index) => { this.subscriptionList.forEach((channel, index) => {
console.log(channel);
if (channel.checked) { if (channel.checked) {
subDb.update({ removeSubscription(channel.channelId, editProfileView.profileName, false);
channelId: channel.channelId,
}, {
$pull: {
profile: {
value: editProfileView.profileName
}
}
}, {
multi: true
}, (err, numRemoved) => {
if (err) {
console.log(err);
}
let subMap = subscriptionView.fullVideoList.map(x => x.author === channel.channelName);
for (let i = 0; i < subMap.length; i++) { let subViewListMap = subscriptionView.fullVideoList.map(x => x.author === channel.channelName);
if (subMap[i]) {
for (let i = 0; i < subViewListMap.length; i++) {
if (subViewListMap[i]) {
let subProfileIndex = subscriptionView.fullVideoList[i].profile.findIndex(x => x.value === editProfileView.profileName); let subProfileIndex = subscriptionView.fullVideoList[i].profile.findIndex(x => x.value === editProfileView.profileName);
subscriptionView.fullVideoList[i].profile.splice(subProfileIndex, 1); subscriptionView.fullVideoList[i].profile.splice(subProfileIndex, 1);
} }
} }
editProfileView.subscriptionList.splice(index, 1); amountDeleted++;
});
amountDeleted++;
} }
}); });
window.setTimeout(() => { window.setTimeout(() => {
// Refresh the list of subscriptions on the side navigation bar and subscriptions view. // Refresh the list of subscriptions on the side navigation bar and subscriptions view.
displaySubs(); displaySubs();
addSubsToView(subscriptionView.fullVideoList); addSubsToView(subscriptionView.fullVideoList);
showToast(amountDeleted + ' channel(s) have been deleted from this profile.'); showToast(amountDeleted + ' channel(s) have been deleted from this profile.');
this.subscriptionList = this.subscriptionList.filter(a => {
return !a.checked;
});
}, 500); }, 500);
}); });
}, },
}, },
computed: { computed: {
newProfileColor: function () {
if (this.newProfileColorText[0] === '#') {
return this.newProfileColorText;
}
else {
return '#' + this.newProfileColorText;
}
},
isDefaultProfile: function () { isDefaultProfile: function () {
return settingsView.defaultProfile === this.profileName; return settingsView.defaultProfile === this.profileName;
}, },

View File

@ -15,10 +15,17 @@
along with FreeTube. If not, see <http://www.gnu.org/licenses/>. along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
*/ */
.channelDefaultBanner {
width: 100%;
height: 200px;
}
.channelViewBanner { .channelViewBanner {
width: 100%; width: 100%;
max-height: 200px; max-height: 200px;
margin-bottom: 30px; margin-bottom: 30px;
background-color: black;
background-image: url('../images/defaultBanner.png');
} }
.channelViewImage { .channelViewImage {

View File

@ -322,13 +322,13 @@ a {
.searchBar { .searchBar {
position: absolute; position: absolute;
right: -75px; left: 40%;
top: 0; top: 0;
width: 750px; width: 650px;
} }
.searchBar input { .searchBar input {
width: 75%; width: 94%;
color: black; color: black;
} }
@ -558,21 +558,25 @@ a {
#confirmFunction { #confirmFunction {
position: fixed; position: fixed;
margin-left: 250px;
margin-right: auto;
left: 4%;
right: 4%;
top: 50%; top: 50%;
left: 30%; height: 45px;
width: 800px; line-height: 45px;
height: 65px; padding: 10px;
font-weight: bold;
line-height: 65px;
visibility: hidden;
z-index: 1; z-index: 1;
-webkit-box-shadow: 5px 5px 15px -5px rgba(0, 0, 0, 0.75); visibility: hidden;
-moz-box-shadow: 5px 5px 15px -5px rgba(0, 0, 0, 0.75); -webkit-box-shadow: 4px -2px 51px -6px rgba(0, 0, 0, 0.75);
box-shadow: 5px 5px 15px -5px rgba(0, 0, 0, 0.75); -webkit-transition: opacity 0.4s ease-in-out;
-moz-transition: opacity 0.4s ease-in-out;
-ms-transition: opacity 0.4s ease-in-out;
-o-transition: opacity 0.4s ease-in-out;
} }
#confirmMessage { #confirmMessage {
margin-left: 15px; font-weight: bold;
} }
.confirmButton { .confirmButton {
@ -583,11 +587,15 @@ a {
#confirmYes { #confirmYes {
right: 90px; right: 90px;
line-height: 65px;
font-weight: bold;
color: #2196f3; color: #2196f3;
} }
#confirmNo { #confirmNo {
right: 20px; right: 20px;
line-height: 65px;
font-weight: bold;
} }
#getNextPage { #getNextPage {

View File

@ -1,5 +1,10 @@
<div v-if='seen'> <div v-if='seen'>
<div v-if='!isNewProfile' class='card'> <div v-if='!isNewProfile' class='card'>
<div v-if="subscriptionList.length === 0" >
<h2>Subscription List for {{profileName}} Profile</h2>
<h4>This profile is empty. Add subscriptions to this profile to manage them.</h4>
</div>
<div v-else >
<h2>Subscription List for {{profileName}} Profile</h2> <h2>Subscription List for {{profileName}} Profile</h2>
<h3>{{amountSelected}} Selected</h3> <h3>{{amountSelected}} Selected</h3>
<br /> <br />
@ -10,6 +15,24 @@
<div class='profileEditName'><span>{{channel.channelName}}</span></div> <div class='profileEditName'><span>{{channel.channelName}}</span></div>
</div> </div>
<br /><br /><br /> <br /><br /><br />
<div class='center'>
<div v-on:click='selectAll' class='settingsButton'>
SELECT ALL
</div>
<div v-on:click='selectNone' class='settingsButton'>
SELECT NONE
</div>
<div v-if="profileName !== 'All Channels'" v-on:click='move' class='settingsButton'>
MOVE SELECTED TO
</div>
<div v-on:click='copy' class='settingsButton'>
COPY SELECTED TO
</div>
<div v-on:click='deleteChannel' style='color: #f44336' class='settingsButton'>
DELETE SELECTED
</div>
</div>
<br />
<div class="select center"> <div class="select center">
<select id="profileListSelect" class="select-text" v-model='selectedProfile' required> <select id="profileListSelect" class="select-text" v-model='selectedProfile' required>
<option v-for='profile in profileList' :value='profile.name'>{{profile.name}}</option> <option v-for='profile in profileList' :value='profile.name'>{{profile.name}}</option>
@ -18,29 +41,15 @@
<span class="select-bar"></span> <span class="select-bar"></span>
<label class="select-label">Profile Select</label> <label class="select-label">Profile Select</label>
</div> </div>
<div class='center'> <h4 v-if="profileName === 'All Channels'">NOTE: Deleting a channel from the "All Channels" profile will also delete the channel from all other profiles.</h4>
<div v-on:click='selectAll' class='settingsButton'> </div>
SELECT ALL
</div>
<div v-on:click='selectNone' class='settingsButton'>
SELECT NONE
</div>
<div v-on:click='move' class='settingsButton'>
MOVE SELECTED
</div>
<div v-on:click='copy' class='settingsButton'>
COPY SELECTED
</div>
<div v-on:click='deleteChannel' style='color: #f44336' class='settingsButton'>
DELETE SELECTED
</div>
</div>
</div> </div>
<div class='card'> <div class='card'>
<h2 v-if='isNewProfile'>Add New Profile</h2> <h2 v-if='isNewProfile'>Add New Profile</h2>
<h2 v-if='!isNewProfile'>Edit Profile Attributes</h2> <h2 v-if='!isNewProfile'>Edit Profile Attributes</h2>
<div class="input-text-settings"> <div class="input-text-settings">
<input type="text" placeholder='Profile Name' name="set-name" v-model='newProfileName' /> <input v-if="profileName !== 'All Channels'" type="text" placeholder='Profile Name' name="set-name" v-model='newProfileName' />
<input v-if="profileName === 'All Channels'" type="text" placeholder='Profile Name' name="set-name" v-model='newProfileName' disabled />
</div> </div>
<h3>Color Picker</h3> <h3>Color Picker</h3>
<div class='colorPickerPadding' v-for='(value, key) in colorPalette'> <div class='colorPickerPadding' v-for='(value, key) in colorPalette'>
@ -48,10 +57,11 @@
</div> </div>
<br /> <br />
<div class="input-text-settings"> <div class="input-text-settings">
<input type="text" placeholder='HEX Color' name="set-name" v-model='newProfileColor' /> <input type="text" placeholder='HEX Color' name="set-name" v-model='newProfileColorText' />
</div> </div>
<br /> <br />
<h3>New Profile Color</h3> <h3 v-if='!isNewProfile'>New Profile Color</h3>
<h3 v-if='isNewProfile'>Selected Profile Color</h3>
<div class='colorPickerPadding'> <div class='colorPickerPadding'>
<div class='colorPicker' :style='{ backgroundColor: newProfileColor }'></div> <div class='colorPicker' :style='{ backgroundColor: newProfileColor }'></div>
</div> </div>
@ -66,7 +76,7 @@
<div v-on:click='defaultProfile' class='settingsButton'> <div v-on:click='defaultProfile' class='settingsButton'>
MAKE DEFAULT PROFILE MAKE DEFAULT PROFILE
</div> </div>
<div v-on:click='deleteProfile' style='color: #f44336' class='settingsButton'> <div v-if="profileName !== 'All Channels'" v-on:click='deleteProfile' style='color: #f44336' class='settingsButton'>
DELETE PROFILE DELETE PROFILE
</div> </div>
</div> </div>

View File

@ -10,7 +10,7 @@
</div> </div>
<div class='profileEditPadding' v-on:click='editProfile(true, -1)'> <div class='profileEditPadding' v-on:click='editProfile(true, -1)'>
<div class='profileEdit' style='background-color: #9E9E9E; cursor: pointer;'> <div class='profileEdit' style='background-color: #9E9E9E; cursor: pointer;'>
<i class='profileEditInitial fas fa-plus' style='color: #000000; top: 14px;'></i> <i class='profileEditInitial fas fa-plus' style='color: #000000; top: 14px; left: 0.4px;'></i>
</div> </div>
<div class='profileEditName'><span>Add New Profile</span></div> <div class='profileEditName'><span>Add New Profile</span></div>
</div> </div>