mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 14:56:06 +02:00
refactor: favorites tab (#1177)
* refactor: favorites tab * rm useless characters
This commit is contained in:
+143
-580
@@ -57,11 +57,11 @@ import ChartsTab from './views/tabs/Charts.vue';
|
|||||||
import SideBar from './views/SideBar.vue';
|
import SideBar from './views/SideBar.vue';
|
||||||
import NavMenu from './views/NavMenu.vue';
|
import NavMenu from './views/NavMenu.vue';
|
||||||
import FriendsListTab from './views/tabs/FriendsList.vue';
|
import FriendsListTab from './views/tabs/FriendsList.vue';
|
||||||
|
import FavoritesTab from './views/tabs/Favorites.vue';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import SimpleSwitch from './components/settings/SimpleSwitch.vue';
|
import SimpleSwitch from './components/settings/SimpleSwitch.vue';
|
||||||
import Location from './components/common/Location.vue';
|
import Location from './components/common/Location.vue';
|
||||||
import FavoritesWorldTab from './components/favorites/FavoritesWorldTab.vue';
|
|
||||||
|
|
||||||
// dialogs
|
// dialogs
|
||||||
import WorldDialog from './views/dialogs/WorldDialog.vue';
|
import WorldDialog from './views/dialogs/WorldDialog.vue';
|
||||||
@@ -198,6 +198,7 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
ModerationTab,
|
ModerationTab,
|
||||||
ChartsTab,
|
ChartsTab,
|
||||||
FriendsListTab,
|
FriendsListTab,
|
||||||
|
FavoritesTab,
|
||||||
// - others
|
// - others
|
||||||
SideBar,
|
SideBar,
|
||||||
NavMenu,
|
NavMenu,
|
||||||
@@ -205,8 +206,7 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
// components
|
// components
|
||||||
// - common
|
// - common
|
||||||
Location,
|
Location,
|
||||||
// - favorites
|
|
||||||
FavoritesWorldTab,
|
|
||||||
// - settings
|
// - settings
|
||||||
SimpleSwitch,
|
SimpleSwitch,
|
||||||
|
|
||||||
@@ -5829,23 +5829,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.clearFavoriteGroup = function (ctx) {
|
|
||||||
// FIXME: 메시지 수정
|
|
||||||
this.$confirm('Continue? Clear Group', 'Confirm', {
|
|
||||||
confirmButtonText: 'Confirm',
|
|
||||||
cancelButtonText: 'Cancel',
|
|
||||||
type: 'info',
|
|
||||||
callback: (action) => {
|
|
||||||
if (action === 'confirm') {
|
|
||||||
favoriteRequest.clearFavoriteGroup({
|
|
||||||
type: ctx.type,
|
|
||||||
group: ctx.name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.computed.favoriteFriends = function () {
|
$app.computed.favoriteFriends = function () {
|
||||||
if (this.sortFavoriteFriends) {
|
if (this.sortFavoriteFriends) {
|
||||||
this.sortFavoriteFriends = false;
|
this.sortFavoriteFriends = false;
|
||||||
@@ -5894,20 +5877,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
return this.favoriteAvatarsSorted;
|
return this.favoriteAvatarsSorted;
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.computed.groupedByGroupKeyFavoriteAvatars = function () {
|
|
||||||
const groupedByGroupKeyFavoriteAvatars = {};
|
|
||||||
this.favoriteAvatars.forEach((avatar) => {
|
|
||||||
if (avatar.groupKey) {
|
|
||||||
if (!groupedByGroupKeyFavoriteAvatars[avatar.groupKey]) {
|
|
||||||
groupedByGroupKeyFavoriteAvatars[avatar.groupKey] = [];
|
|
||||||
}
|
|
||||||
groupedByGroupKeyFavoriteAvatars[avatar.groupKey].push(avatar);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return groupedByGroupKeyFavoriteAvatars;
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: friendLog
|
// #region | App: friendLog
|
||||||
|
|
||||||
@@ -10947,7 +10916,7 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
D.timeSpent = 0;
|
D.timeSpent = 0;
|
||||||
D.isFavorite =
|
D.isFavorite =
|
||||||
API.cachedFavoritesByObjectId.has(avatarId) ||
|
API.cachedFavoritesByObjectId.has(avatarId) ||
|
||||||
(this.isLocalUserVrcplusSupporter() &&
|
(API.currentUser.$isVRCPlus &&
|
||||||
this.localAvatarFavoritesList.includes(avatarId));
|
this.localAvatarFavoritesList.includes(avatarId));
|
||||||
D.isBlocked = API.cachedAvatarModerations.has(avatarId);
|
D.isBlocked = API.cachedAvatarModerations.has(avatarId);
|
||||||
D.memo = '';
|
D.memo = '';
|
||||||
@@ -11418,24 +11387,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.addFavoriteAvatar = function (ref, group, message) {
|
|
||||||
return favoriteRequest
|
|
||||||
.addFavorite({
|
|
||||||
type: 'avatar',
|
|
||||||
favoriteId: ref.id,
|
|
||||||
tags: group.name
|
|
||||||
})
|
|
||||||
.then((args) => {
|
|
||||||
if (message) {
|
|
||||||
this.$message({
|
|
||||||
message: 'Avatar added to favorites',
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.addFavoriteUser = function (ref, group, message) {
|
$app.methods.addFavoriteUser = function (ref, group, message) {
|
||||||
return favoriteRequest
|
return favoriteRequest
|
||||||
.addFavorite({
|
.addFavorite({
|
||||||
@@ -18274,119 +18225,8 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
$app.worldImportDialog.visible = false;
|
$app.worldImportDialog.visible = false;
|
||||||
$app.worldImportFavoriteGroup = null;
|
$app.worldImportFavoriteGroup = null;
|
||||||
$app.worldImportLocalFavoriteGroup = null;
|
$app.worldImportLocalFavoriteGroup = null;
|
||||||
|
|
||||||
$app.worldExportDialogVisible = false;
|
|
||||||
$app.worldExportFavoriteGroup = null;
|
|
||||||
$app.worldExportLocalFavoriteGroup = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// #endregion
|
|
||||||
// #region | App: world favorite export
|
|
||||||
|
|
||||||
$app.data.worldExportDialogRef = {};
|
|
||||||
$app.data.worldExportDialogVisible = false;
|
|
||||||
$app.data.worldExportContent = '';
|
|
||||||
$app.data.worldExportFavoriteGroup = null;
|
|
||||||
$app.data.worldExportLocalFavoriteGroup = null;
|
|
||||||
|
|
||||||
$app.methods.showWorldExportDialog = function () {
|
|
||||||
this.$nextTick(() =>
|
|
||||||
$app.adjustDialogZ(this.$refs.worldExportDialogRef.$el)
|
|
||||||
);
|
|
||||||
this.worldExportFavoriteGroup = null;
|
|
||||||
this.worldExportLocalFavoriteGroup = null;
|
|
||||||
this.updateWorldExportDialog();
|
|
||||||
this.worldExportDialogVisible = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.handleCopyWorldExportData = function (event) {
|
|
||||||
event.target.tagName === 'TEXTAREA' && event.target.select();
|
|
||||||
navigator.clipboard
|
|
||||||
.writeText(this.worldExportContent)
|
|
||||||
.then(() => {
|
|
||||||
this.$message({
|
|
||||||
message: 'Copied successfully!',
|
|
||||||
type: 'success',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error('Copy failed:', err);
|
|
||||||
this.$message.error('Copy failed!');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.updateWorldExportDialog = function () {
|
|
||||||
const formatter = function (str) {
|
|
||||||
if (/[\x00-\x1f,"]/.test(str) === true) {
|
|
||||||
return `"${str.replace(/"/g, '""')}"`;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
function resText(ref) {
|
|
||||||
let resArr = [];
|
|
||||||
propsForQuery.forEach((e) => {
|
|
||||||
resArr.push(formatter(ref?.[e]));
|
|
||||||
});
|
|
||||||
return resArr.join(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = [this.exportSelectedOptions.join(',')];
|
|
||||||
const propsForQuery = this.exportSelectOptions
|
|
||||||
.filter((option) =>
|
|
||||||
this.exportSelectedOptions.includes(option.label)
|
|
||||||
)
|
|
||||||
.map((option) => option.value);
|
|
||||||
|
|
||||||
if (this.worldExportFavoriteGroup) {
|
|
||||||
API.favoriteWorldGroups.forEach((group) => {
|
|
||||||
if (this.worldExportFavoriteGroup === group) {
|
|
||||||
$app.favoriteWorlds.forEach((ref) => {
|
|
||||||
if (group.key === ref.groupKey) {
|
|
||||||
lines.push(resText(ref.ref));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (this.worldExportLocalFavoriteGroup) {
|
|
||||||
const favoriteGroup =
|
|
||||||
this.localWorldFavorites[this.worldExportLocalFavoriteGroup];
|
|
||||||
if (!favoriteGroup) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < favoriteGroup.length; ++i) {
|
|
||||||
const ref = favoriteGroup[i];
|
|
||||||
lines.push(resText(ref));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// export all
|
|
||||||
this.favoriteWorlds.forEach((ref) => {
|
|
||||||
lines.push(resText(ref.ref));
|
|
||||||
});
|
|
||||||
for (let i = 0; i < this.localWorldFavoritesList.length; ++i) {
|
|
||||||
const worldId = this.localWorldFavoritesList[i];
|
|
||||||
const ref = API.cachedWorlds.get(worldId);
|
|
||||||
if (typeof ref !== 'undefined') {
|
|
||||||
lines.push(resText(ref));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.worldExportContent = lines.join('\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.selectWorldExportGroup = function (group) {
|
|
||||||
this.worldExportFavoriteGroup = group;
|
|
||||||
this.worldExportLocalFavoriteGroup = null;
|
|
||||||
this.updateWorldExportDialog();
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.selectWorldExportLocalGroup = function (group) {
|
|
||||||
this.worldExportLocalFavoriteGroup = group;
|
|
||||||
this.worldExportFavoriteGroup = null;
|
|
||||||
this.updateWorldExportDialog();
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: avatar favorite import
|
// #region | App: avatar favorite import
|
||||||
|
|
||||||
@@ -18502,6 +18342,23 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.importAvatarImportTable = async function () {
|
$app.methods.importAvatarImportTable = async function () {
|
||||||
|
const addFavoriteAvatar = function (ref, group, message) {
|
||||||
|
return favoriteRequest
|
||||||
|
.addFavorite({
|
||||||
|
type: 'avatar',
|
||||||
|
favoriteId: ref.id,
|
||||||
|
tags: group.name
|
||||||
|
})
|
||||||
|
.then((args) => {
|
||||||
|
if (message) {
|
||||||
|
this.$message({
|
||||||
|
message: 'Avatar added to favorites',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
});
|
||||||
|
};
|
||||||
var D = this.avatarImportDialog;
|
var D = this.avatarImportDialog;
|
||||||
if (!D.avatarImportFavoriteGroup && !D.avatarImportLocalFavoriteGroup) {
|
if (!D.avatarImportFavoriteGroup && !D.avatarImportLocalFavoriteGroup) {
|
||||||
return;
|
return;
|
||||||
@@ -18516,7 +18373,7 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
}
|
}
|
||||||
var ref = data[i];
|
var ref = data[i];
|
||||||
if (D.avatarImportFavoriteGroup) {
|
if (D.avatarImportFavoriteGroup) {
|
||||||
await this.addFavoriteAvatar(
|
await addFavoriteAvatar(
|
||||||
ref,
|
ref,
|
||||||
D.avatarImportFavoriteGroup,
|
D.avatarImportFavoriteGroup,
|
||||||
false
|
false
|
||||||
@@ -18546,136 +18403,8 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
$app.avatarImportDialog.visible = false;
|
$app.avatarImportDialog.visible = false;
|
||||||
$app.avatarImportFavoriteGroup = null;
|
$app.avatarImportFavoriteGroup = null;
|
||||||
$app.avatarImportLocalFavoriteGroup = null;
|
$app.avatarImportLocalFavoriteGroup = null;
|
||||||
|
|
||||||
$app.avatarExportDialogVisible = false;
|
|
||||||
$app.avatarExportFavoriteGroup = null;
|
|
||||||
$app.avatarExportLocalFavoriteGroup = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// #endregion
|
|
||||||
// #region | App: avatar favorite export
|
|
||||||
|
|
||||||
$app.data.avatarExportDialogRef = {};
|
|
||||||
$app.data.avatarExportDialogVisible = false;
|
|
||||||
$app.data.avatarExportContent = '';
|
|
||||||
$app.data.avatarExportFavoriteGroup = null;
|
|
||||||
$app.data.avatarExportLocalFavoriteGroup = null;
|
|
||||||
|
|
||||||
// Storage of selected filtering options for model and world export
|
|
||||||
$app.data.exportSelectedOptions = ['ID', 'Name'];
|
|
||||||
$app.data.exportSelectOptions = [
|
|
||||||
{ label: 'ID', value: 'id' },
|
|
||||||
{ label: 'Name', value: 'name' },
|
|
||||||
{ label: 'Author ID', value: 'authorId' },
|
|
||||||
{ label: 'Author Name', value: 'authorName' },
|
|
||||||
{ label: 'Thumbnail', value: 'thumbnailImageUrl' }
|
|
||||||
];
|
|
||||||
|
|
||||||
$app.methods.showAvatarExportDialog = function () {
|
|
||||||
this.$nextTick(() =>
|
|
||||||
$app.adjustDialogZ(this.$refs.avatarExportDialogRef.$el)
|
|
||||||
);
|
|
||||||
this.avatarExportFavoriteGroup = null;
|
|
||||||
this.avatarExportLocalFavoriteGroup = null;
|
|
||||||
this.updateAvatarExportDialog();
|
|
||||||
this.avatarExportDialogVisible = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.handleCopyAvatarExportData = function (event) {
|
|
||||||
event.target.tagName === 'TEXTAREA' && event.target.select();
|
|
||||||
navigator.clipboard
|
|
||||||
.writeText(this.avatarExportContent)
|
|
||||||
.then(() => {
|
|
||||||
this.$message({
|
|
||||||
message: 'Copied successfully!',
|
|
||||||
type: 'success',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error('Copy failed:', err);
|
|
||||||
this.$message.error('Copy failed!');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the content of the avatar export dialog based on the selected options
|
|
||||||
*/
|
|
||||||
|
|
||||||
$app.methods.updateAvatarExportDialog = function () {
|
|
||||||
const formatter = function (str) {
|
|
||||||
if (/[\x00-\x1f,"]/.test(str) === true) {
|
|
||||||
return `"${str.replace(/"/g, '""')}"`;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
function resText(ref) {
|
|
||||||
let resArr = [];
|
|
||||||
propsForQuery.forEach((e) => {
|
|
||||||
resArr.push(formatter(ref?.[e]));
|
|
||||||
});
|
|
||||||
return resArr.join(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = [this.exportSelectedOptions.join(',')];
|
|
||||||
const propsForQuery = this.exportSelectOptions
|
|
||||||
.filter((option) =>
|
|
||||||
this.exportSelectedOptions.includes(option.label)
|
|
||||||
)
|
|
||||||
.map((option) => option.value);
|
|
||||||
|
|
||||||
if (this.avatarExportFavoriteGroup) {
|
|
||||||
API.favoriteAvatarGroups.forEach((group) => {
|
|
||||||
if (
|
|
||||||
!this.avatarExportFavoriteGroup ||
|
|
||||||
this.avatarExportFavoriteGroup === group
|
|
||||||
) {
|
|
||||||
$app.favoriteAvatars.forEach((ref) => {
|
|
||||||
if (group.key === ref.groupKey) {
|
|
||||||
lines.push(resText(ref.ref));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (this.avatarExportLocalFavoriteGroup) {
|
|
||||||
const favoriteGroup =
|
|
||||||
this.localAvatarFavorites[this.avatarExportLocalFavoriteGroup];
|
|
||||||
if (!favoriteGroup) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < favoriteGroup.length; ++i) {
|
|
||||||
const ref = favoriteGroup[i];
|
|
||||||
lines.push(resText(ref));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// export all
|
|
||||||
this.favoriteAvatars.forEach((ref) => {
|
|
||||||
lines.push(resText(ref.ref));
|
|
||||||
});
|
|
||||||
for (let i = 0; i < this.localAvatarFavoritesList.length; ++i) {
|
|
||||||
const avatarId = this.localAvatarFavoritesList[i];
|
|
||||||
const ref = API.cachedAvatars.get(avatarId);
|
|
||||||
if (typeof ref !== 'undefined') {
|
|
||||||
lines.push(resText(ref));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.avatarExportContent = lines.join('\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.selectAvatarExportGroup = function (group) {
|
|
||||||
this.avatarExportFavoriteGroup = group;
|
|
||||||
this.avatarExportLocalFavoriteGroup = null;
|
|
||||||
this.updateAvatarExportDialog();
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.selectAvatarExportLocalGroup = function (group) {
|
|
||||||
this.avatarExportLocalFavoriteGroup = group;
|
|
||||||
this.avatarExportFavoriteGroup = null;
|
|
||||||
this.updateAvatarExportDialog();
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: friend favorite import
|
// #region | App: friend favorite import
|
||||||
|
|
||||||
@@ -18822,68 +18551,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
$app.friendExportFavoriteGroup = null;
|
$app.friendExportFavoriteGroup = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
// #endregion
|
|
||||||
// #region | App: friend favorite export
|
|
||||||
|
|
||||||
$app.data.friendExportDialogRef = {};
|
|
||||||
$app.data.friendExportDialogVisible = false;
|
|
||||||
$app.data.friendExportContent = '';
|
|
||||||
$app.data.friendExportFavoriteGroup = null;
|
|
||||||
|
|
||||||
$app.methods.showFriendExportDialog = function () {
|
|
||||||
this.$nextTick(() =>
|
|
||||||
$app.adjustDialogZ(this.$refs.friendExportDialogRef.$el)
|
|
||||||
);
|
|
||||||
this.friendExportFavoriteGroup = null;
|
|
||||||
this.updateFriendExportDialog();
|
|
||||||
this.friendExportDialogVisible = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.handleCopyFriendExportData = function (event) {
|
|
||||||
event.target.tagName === 'TEXTAREA' && event.target.select();
|
|
||||||
navigator.clipboard
|
|
||||||
.writeText(this.friendExportContent)
|
|
||||||
.then(() => {
|
|
||||||
this.$message({
|
|
||||||
message: 'Copied successfully!',
|
|
||||||
type: 'success',
|
|
||||||
duration: 2000
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error('Copy failed:', err);
|
|
||||||
this.$message.error('Copy failed!');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.updateFriendExportDialog = function () {
|
|
||||||
var _ = function (str) {
|
|
||||||
if (/[\x00-\x1f,"]/.test(str) === true) {
|
|
||||||
return `"${str.replace(/"/g, '""')}"`;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
var lines = ['UserID,Name'];
|
|
||||||
API.favoriteFriendGroups.forEach((group) => {
|
|
||||||
if (
|
|
||||||
!this.friendExportFavoriteGroup ||
|
|
||||||
this.friendExportFavoriteGroup === group
|
|
||||||
) {
|
|
||||||
$app.favoriteFriends.forEach((ref) => {
|
|
||||||
if (group.key === ref.groupKey) {
|
|
||||||
lines.push(`${_(ref.id)},${_(ref.name)}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.friendExportContent = lines.join('\n');
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.selectFriendExportGroup = function (group) {
|
|
||||||
this.friendExportFavoriteGroup = group;
|
|
||||||
this.updateFriendExportDialog();
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: user dialog notes
|
// #region | App: user dialog notes
|
||||||
|
|
||||||
@@ -19148,55 +18815,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: bulk unfavorite
|
// #region | App: bulk unfavorite
|
||||||
|
|
||||||
$app.data.editFavoritesMode = false;
|
|
||||||
|
|
||||||
$app.methods.showBulkUnfavoriteSelectionConfirm = function () {
|
|
||||||
var elementsTicked = [];
|
|
||||||
// check favorites type
|
|
||||||
for (var ctx of this.favoriteFriends) {
|
|
||||||
if (ctx.$selected) {
|
|
||||||
elementsTicked.push(ctx.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var ctx of this.favoriteWorlds) {
|
|
||||||
if (ctx.$selected) {
|
|
||||||
elementsTicked.push(ctx.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var ctx of this.favoriteAvatars) {
|
|
||||||
if (ctx.$selected) {
|
|
||||||
elementsTicked.push(ctx.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (elementsTicked.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$confirm(
|
|
||||||
`Are you sure you want to unfavorite ${elementsTicked.length} favorites?
|
|
||||||
This action cannot be undone.`,
|
|
||||||
`Delete ${elementsTicked.length} favorites?`,
|
|
||||||
{
|
|
||||||
confirmButtonText: 'Confirm',
|
|
||||||
cancelButtonText: 'Cancel',
|
|
||||||
type: 'info',
|
|
||||||
callback: (action) => {
|
|
||||||
if (action === 'confirm') {
|
|
||||||
this.bulkUnfavoriteSelection(elementsTicked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.bulkUnfavoriteSelection = function (elementsTicked) {
|
|
||||||
for (var id of elementsTicked) {
|
|
||||||
favoriteRequest.deleteFavorite({
|
|
||||||
objectId: id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.editFavoritesMode = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.bulkCopyFavoriteSelection = function () {
|
$app.methods.bulkCopyFavoriteSelection = function () {
|
||||||
var idList = '';
|
var idList = '';
|
||||||
var type = '';
|
var type = '';
|
||||||
@@ -19498,78 +19116,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
$app.getLocalWorldFavorites();
|
$app.getLocalWorldFavorites();
|
||||||
});
|
});
|
||||||
|
|
||||||
$app.methods.refreshLocalWorldFavorites = async function () {
|
|
||||||
if (this.refreshingLocalFavorites) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.refreshingLocalFavorites = true;
|
|
||||||
for (var worldId of this.localWorldFavoritesList) {
|
|
||||||
if (!this.refreshingLocalFavorites) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await worldRequest.getWorld({
|
|
||||||
worldId
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
workerTimers.setTimeout(resolve, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.refreshingLocalFavorites = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.data.worldFavoriteSearchResults = [];
|
|
||||||
|
|
||||||
$app.methods.searchWorldFavorites = function (worldFavoriteSearch) {
|
|
||||||
var search = worldFavoriteSearch.toLowerCase();
|
|
||||||
if (search.length < 3) {
|
|
||||||
this.worldFavoriteSearchResults = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var results = [];
|
|
||||||
for (var i = 0; i < this.localWorldFavoriteGroups.length; ++i) {
|
|
||||||
var group = this.localWorldFavoriteGroups[i];
|
|
||||||
if (!this.localWorldFavorites[group]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (var j = 0; j < this.localWorldFavorites[group].length; ++j) {
|
|
||||||
var ref = this.localWorldFavorites[group][j];
|
|
||||||
if (!ref || !ref.id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
ref.name.toLowerCase().includes(search) ||
|
|
||||||
ref.authorName.toLowerCase().includes(search)
|
|
||||||
) {
|
|
||||||
if (!results.some((r) => r.id == ref.id)) {
|
|
||||||
results.push(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < this.favoriteWorlds.length; ++i) {
|
|
||||||
var ref = this.favoriteWorlds[i].ref;
|
|
||||||
if (!ref) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
ref.name.toLowerCase().includes(search) ||
|
|
||||||
ref.authorName.toLowerCase().includes(search)
|
|
||||||
) {
|
|
||||||
if (!results.some((r) => r.id == ref.id)) {
|
|
||||||
results.push(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.worldFavoriteSearchResults = results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | App: Local Avatar Favorites
|
// #region | App: Local Avatar Favorites
|
||||||
|
|
||||||
@@ -19744,14 +19290,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.getLocalAvatarFavoriteGroupLength = function (group) {
|
|
||||||
var favoriteGroup = this.localAvatarFavorites[group];
|
|
||||||
if (!favoriteGroup) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return favoriteGroup.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.promptNewLocalAvatarFavoriteGroup = function () {
|
$app.methods.promptNewLocalAvatarFavoriteGroup = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
$t('prompt.new_local_favorite_group.description'),
|
$t('prompt.new_local_favorite_group.description'),
|
||||||
@@ -19932,81 +19470,6 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.data.refreshingLocalFavorites = false;
|
|
||||||
|
|
||||||
$app.methods.refreshLocalAvatarFavorites = async function () {
|
|
||||||
if (this.refreshingLocalFavorites) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.refreshingLocalFavorites = true;
|
|
||||||
for (var avatarId of this.localAvatarFavoritesList) {
|
|
||||||
if (!this.refreshingLocalFavorites) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await avatarRequest.getAvatar({
|
|
||||||
avatarId
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
workerTimers.setTimeout(resolve, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.refreshingLocalFavorites = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.data.avatarFavoriteSearch = '';
|
|
||||||
$app.data.avatarFavoriteSearchResults = [];
|
|
||||||
|
|
||||||
$app.methods.searchAvatarFavorites = function () {
|
|
||||||
var search = this.avatarFavoriteSearch.toLowerCase();
|
|
||||||
if (search.length < 3) {
|
|
||||||
this.avatarFavoriteSearchResults = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var results = [];
|
|
||||||
for (var i = 0; i < this.localAvatarFavoriteGroups.length; ++i) {
|
|
||||||
var group = this.localAvatarFavoriteGroups[i];
|
|
||||||
if (!this.localAvatarFavorites[group]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (var j = 0; j < this.localAvatarFavorites[group].length; ++j) {
|
|
||||||
var ref = this.localAvatarFavorites[group][j];
|
|
||||||
if (!ref || !ref.id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
ref.name.toLowerCase().includes(search) ||
|
|
||||||
ref.authorName.toLowerCase().includes(search)
|
|
||||||
) {
|
|
||||||
if (!results.some((r) => r.id == ref.id)) {
|
|
||||||
results.push(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < this.favoriteAvatars.length; ++i) {
|
|
||||||
var ref = this.favoriteAvatars[i].ref;
|
|
||||||
if (!ref) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
ref.name.toLowerCase().includes(search) ||
|
|
||||||
ref.authorName.toLowerCase().includes(search)
|
|
||||||
) {
|
|
||||||
if (!results.some((r) => r.id == ref.id)) {
|
|
||||||
results.push(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.avatarFavoriteSearchResults = results;
|
|
||||||
};
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
// #region | Local Favorite Friends
|
// #region | Local Favorite Friends
|
||||||
|
|
||||||
@@ -20124,6 +19587,14 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$app.methods.getLocalAvatarFavoriteGroupLength = function (group) {
|
||||||
|
var favoriteGroup = this.localAvatarFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return favoriteGroup.length;
|
||||||
|
};
|
||||||
|
|
||||||
$app.methods.saveChatboxUserBlacklist = async function () {
|
$app.methods.saveChatboxUserBlacklist = async function () {
|
||||||
await configRepository.setString(
|
await configRepository.setString(
|
||||||
'VRCX_chatboxUserBlacklist',
|
'VRCX_chatboxUserBlacklist',
|
||||||
@@ -21089,8 +20560,41 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
// #region | Tab Props
|
// #region | Tab Props
|
||||||
$app.computed.sideBarTabProps = function () {
|
|
||||||
|
$app.computed.moderationTabBind = function () {
|
||||||
return {
|
return {
|
||||||
|
menuActiveIndex: this.menuActiveIndex,
|
||||||
|
tableData: this.playerModerationTable,
|
||||||
|
shiftHeld: this.shiftHeld,
|
||||||
|
hideTooltips: this.hideTooltips
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.computed.friendsListTabBind = function () {
|
||||||
|
return {
|
||||||
|
menuActiveIndex: this.menuActiveIndex,
|
||||||
|
friends: this.friends,
|
||||||
|
hideTooltips: this.hideTooltips,
|
||||||
|
randomUserColours: this.randomUserColours,
|
||||||
|
sortStatus: this.sortStatus,
|
||||||
|
languageClass: this.languageClass,
|
||||||
|
confirmDeleteFriend: this.confirmDeleteFriend,
|
||||||
|
friendsListSearch: this.friendsListSearch,
|
||||||
|
stringComparer: this.stringComparer
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$app.computed.friendsListTabEvent = function () {
|
||||||
|
return {
|
||||||
|
'get-all-user-stats': this.getAllUserStats,
|
||||||
|
'lookup-user': this.lookupUser,
|
||||||
|
'update:friends-list-search': (value) =>
|
||||||
|
(this.friendsListSearch = value)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.computed.sideBarTabBind = function () {
|
||||||
|
return {
|
||||||
|
isSideBarTabShow: this.isSideBarTabShow,
|
||||||
style: { width: `${this.asideWidth}px` },
|
style: { width: `${this.asideWidth}px` },
|
||||||
vipFriends: this.vipFriends,
|
vipFriends: this.vipFriends,
|
||||||
onlineFriends: this.onlineFriends,
|
onlineFriends: this.onlineFriends,
|
||||||
@@ -21116,6 +20620,16 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.computed.sideBarTabEvent = function () {
|
||||||
|
return {
|
||||||
|
'show-group-dialog': this.showGroupDialog,
|
||||||
|
'quick-search-change': this.quickSearchChange,
|
||||||
|
'direct-access-paste': this.directAccessPaste,
|
||||||
|
'refresh-friends-list': this.refreshFriendsList,
|
||||||
|
'confirm-delete-friend': this.confirmDeleteFriend
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
$app.computed.isSideBarTabShow = function () {
|
$app.computed.isSideBarTabShow = function () {
|
||||||
return !(
|
return !(
|
||||||
this.menuActiveIndex === 'friendsList' ||
|
this.menuActiveIndex === 'friendsList' ||
|
||||||
@@ -21123,28 +20637,77 @@ console.log(`isLinux: ${LINUX}`);
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// #endregion
|
$app.computed.favoritesTabBind = function () {
|
||||||
|
return {
|
||||||
// favWorldItem have to be defined
|
menuActiveIndex: this.menuActiveIndex,
|
||||||
$app.methods.deleteFavorite = function (objectId) {
|
hideTooltips: this.hideTooltips,
|
||||||
favoriteRequest.deleteFavorite({
|
shiftHeld: this.shiftHeld,
|
||||||
objectId
|
favoriteFriends: this.favoriteFriends,
|
||||||
});
|
sortFavorites: this.sortFavorites,
|
||||||
// FIXME: 메시지 수정
|
groupedByGroupKeyFavoriteFriends:
|
||||||
// this.$confirm('Continue? Delete Favorite', 'Confirm', {
|
this.groupedByGroupKeyFavoriteFriends,
|
||||||
// confirmButtonText: 'Confirm',
|
favoriteWorlds: this.favoriteWorlds,
|
||||||
// cancelButtonText: 'Cancel',
|
localWorldFavoriteGroups: this.localWorldFavoriteGroups,
|
||||||
// type: 'info',
|
localWorldFavorites: this.localWorldFavorites,
|
||||||
// callback: (action) => {
|
avatarHistoryArray: this.avatarHistoryArray,
|
||||||
// if (action === 'confirm') {
|
localAvatarFavoriteGroups: this.localAvatarFavoriteGroups,
|
||||||
// API.deleteFavorite({
|
localAvatarFavorites: this.localAvatarFavorites,
|
||||||
// objectId
|
favoriteAvatars: this.favoriteAvatars,
|
||||||
// });
|
localAvatarFavoritesList: this.localAvatarFavoritesList,
|
||||||
// }
|
localWorldFavoritesList: this.localWorldFavoritesList
|
||||||
// }
|
};
|
||||||
// });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.computed.favoritesTabEvent = function () {
|
||||||
|
return {
|
||||||
|
'update:sort-favorites': (value) => (this.sortFavorites = value),
|
||||||
|
'clear-bulk-favorite-selection': this.clearBulkFavoriteSelection,
|
||||||
|
'bulk-copy-favorite-selection': this.bulkCopyFavoriteSelection,
|
||||||
|
'get-local-world-favorites': this.getLocalWorldFavorites,
|
||||||
|
'show-friend-import-dialog': this.showFriendImportDialog,
|
||||||
|
'save-sort-favorites-option': this.saveSortFavoritesOption,
|
||||||
|
'show-world-import-dialog': this.showWorldImportDialog,
|
||||||
|
'show-world-dialog': this.showWorldDialog,
|
||||||
|
'new-instance-self-invite': this.newInstanceSelfInvite,
|
||||||
|
'show-favorite-dialog': this.showFavoriteDialog,
|
||||||
|
'delete-local-world-favorite-group':
|
||||||
|
this.deleteLocalWorldFavoriteGroup,
|
||||||
|
'remove-local-world-favorite': this.removeLocalWorldFavorite,
|
||||||
|
'show-avatar-import-dialog': this.showAvatarImportDialog,
|
||||||
|
'show-avatar-dialog': this.showAvatarDialog,
|
||||||
|
'remove-local-avatar-favorite': this.removeLocalAvatarFavorite,
|
||||||
|
'select-avatar-with-confirmation':
|
||||||
|
this.selectAvatarWithConfirmation,
|
||||||
|
'prompt-clear-avatar-history': this.promptClearAvatarHistory,
|
||||||
|
'prompt-new-local-avatar-favorite-group':
|
||||||
|
this.promptNewLocalAvatarFavoriteGroup,
|
||||||
|
'prompt-local-avatar-favorite-group-rename':
|
||||||
|
this.promptLocalAvatarFavoriteGroupRename,
|
||||||
|
'prompt-local-avatar-favorite-group-delete':
|
||||||
|
this.promptLocalAvatarFavoriteGroupDelete,
|
||||||
|
'new-local-world-favorite-group': this.newLocalWorldFavoriteGroup,
|
||||||
|
'rename-local-world-favorite-group':
|
||||||
|
this.renameLocalWorldFavoriteGroup
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.computed.chartsTabBind = function () {
|
||||||
|
return {
|
||||||
|
getWorldName: this.getWorldName,
|
||||||
|
isDarkMode: this.isDarkMode,
|
||||||
|
dtHour12: this.dtHour12,
|
||||||
|
friendsMap: this.friends,
|
||||||
|
localFavoriteFriends: this.localFavoriteFriends
|
||||||
|
};
|
||||||
|
};
|
||||||
|
$app.computed.chartsTabEvent = function () {
|
||||||
|
return {
|
||||||
|
'open-previous-instance-info-dialog':
|
||||||
|
this.showPreviousInstanceInfoDialog
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// #endregion
|
||||||
|
|
||||||
// #region | Electron
|
// #region | Electron
|
||||||
|
|
||||||
if (LINUX) {
|
if (LINUX) {
|
||||||
|
|||||||
+5
-36
@@ -43,20 +43,14 @@ doctype html
|
|||||||
include ./mixins/tabs/search.pug
|
include ./mixins/tabs/search.pug
|
||||||
+searchTab
|
+searchTab
|
||||||
|
|
||||||
//- favorite
|
favorites-tab(v-bind='favoritesTabBind' v-on='favoritesTabEvent')
|
||||||
include ./mixins/tabs/favorites.pug
|
|
||||||
+favoritesTab
|
|
||||||
|
|
||||||
//- friendLog
|
//- friendLog
|
||||||
include ./mixins/tabs/friendLog.pug
|
include ./mixins/tabs/friendLog.pug
|
||||||
+friendLogTab
|
+friendLogTab
|
||||||
|
|
||||||
//- moderation
|
//- moderation
|
||||||
moderation-tab(
|
moderation-tab(v-bind='moderationTabBind')
|
||||||
v-if='menuActiveIndex === "moderation"'
|
|
||||||
:table-data='playerModerationTable'
|
|
||||||
:shift-held='shiftHeld'
|
|
||||||
:hide-tooltips='hideTooltips')
|
|
||||||
|
|
||||||
//- notification
|
//- notification
|
||||||
include ./mixins/tabs/notifications.pug
|
include ./mixins/tabs/notifications.pug
|
||||||
@@ -67,42 +61,17 @@ doctype html
|
|||||||
+profileTab
|
+profileTab
|
||||||
|
|
||||||
//- friends list
|
//- friends list
|
||||||
friends-list-tab(
|
friends-list-tab(v-bind='friendsListTabBind' v-on='friendsListTabEvent')
|
||||||
:menu-active-index='menuActiveIndex'
|
|
||||||
:friends='friends'
|
|
||||||
:hide-tooltips='hideTooltips'
|
|
||||||
:random-user-colours='randomUserColours'
|
|
||||||
:sort-status='sortStatus'
|
|
||||||
:language-class='languageClass'
|
|
||||||
:confirm-delete-friend='confirmDeleteFriend'
|
|
||||||
:friends-list-search.sync='friendsListSearch'
|
|
||||||
@get-all-user-stats='getAllUserStats'
|
|
||||||
@lookup-user='lookupUser'
|
|
||||||
:string-comparer='stringComparer')
|
|
||||||
|
|
||||||
//- charts
|
//- charts
|
||||||
keep-alive
|
keep-alive
|
||||||
charts-tab(
|
charts-tab(v-if='menuActiveIndex === "charts"' v-bind='chartsTabBind' v-on='chartsTabEvent')
|
||||||
v-if='menuActiveIndex === "charts"'
|
|
||||||
:get-world-name='getWorldName'
|
|
||||||
:is-dark-mode='isDarkMode'
|
|
||||||
:dt-hour12='dtHour12'
|
|
||||||
:friends-map='friends'
|
|
||||||
:local-favorite-friends='localFavoriteFriends'
|
|
||||||
@open-previous-instance-info-dialog='showPreviousInstanceInfoDialog')
|
|
||||||
|
|
||||||
//- settings
|
//- settings
|
||||||
include ./mixins/tabs/settings.pug
|
include ./mixins/tabs/settings.pug
|
||||||
+settingsTab
|
+settingsTab
|
||||||
|
|
||||||
side-bar(
|
side-bar(v-bind='sideBarTabBind' v-on='sideBarTabEvent')
|
||||||
v-show='isSideBarTabShow'
|
|
||||||
v-bind='sideBarTabProps'
|
|
||||||
@show-group-dialog='showGroupDialog'
|
|
||||||
@quick-search-change='quickSearchChange'
|
|
||||||
@direct-access-paste='directAccessPaste'
|
|
||||||
@refresh-friends-list='refreshFriendsList'
|
|
||||||
@confirm-delete-friend='confirmDeleteFriend')
|
|
||||||
|
|
||||||
//- ## Dialogs ## -\\
|
//- ## Dialogs ## -\\
|
||||||
include ./mixins/dialogs/userDialog.pug
|
include ./mixins/dialogs/userDialog.pug
|
||||||
|
|||||||
@@ -294,51 +294,6 @@ export default class extends baseClass {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
// remove when finished fav tab split
|
|
||||||
changeFavoriteGroupName(ctx) {
|
|
||||||
this.$prompt(
|
|
||||||
$t('prompt.change_favorite_group_name.description'),
|
|
||||||
$t('prompt.change_favorite_group_name.header'),
|
|
||||||
{
|
|
||||||
distinguishCancelAndClose: true,
|
|
||||||
cancelButtonText: $t(
|
|
||||||
'prompt.change_favorite_group_name.cancel'
|
|
||||||
),
|
|
||||||
confirmButtonText: $t(
|
|
||||||
'prompt.change_favorite_group_name.change'
|
|
||||||
),
|
|
||||||
inputPlaceholder: $t(
|
|
||||||
'prompt.change_favorite_group_name.input_placeholder'
|
|
||||||
),
|
|
||||||
inputValue: ctx.displayName,
|
|
||||||
inputPattern: /\S+/,
|
|
||||||
inputErrorMessage: $t(
|
|
||||||
'prompt.change_favorite_group_name.input_error'
|
|
||||||
),
|
|
||||||
callback: (action, instance) => {
|
|
||||||
if (action === 'confirm') {
|
|
||||||
favoriteRequest
|
|
||||||
.saveFavoriteGroup({
|
|
||||||
type: ctx.type,
|
|
||||||
group: ctx.name,
|
|
||||||
displayName: instance.inputValue
|
|
||||||
})
|
|
||||||
.then((args) => {
|
|
||||||
this.$message({
|
|
||||||
message: $t(
|
|
||||||
'prompt.change_favorite_group_name.message.success'
|
|
||||||
),
|
|
||||||
type: 'success'
|
|
||||||
});
|
|
||||||
// load new group name
|
|
||||||
API.refreshFavoriteGroups();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
promptNotificationTimeout() {
|
promptNotificationTimeout() {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
$t('prompt.notification_timeout.description'),
|
$t('prompt.notification_timeout.description'),
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
isNextDayBtnDisabled() {
|
isNextDayBtnDisabled() {
|
||||||
return dayjs(this.selectedDate).isSame(dayjs(), 'day');
|
return dayjs(this.selectedDate).isSame(this.allDateOfActivityArray[0], 'day');
|
||||||
},
|
},
|
||||||
isPrevDayBtnDisabled() {
|
isPrevDayBtnDisabled() {
|
||||||
return dayjs(this.selectedDate).isSame(
|
return dayjs(this.selectedDate).isSame(
|
||||||
@@ -535,18 +535,24 @@
|
|||||||
|
|
||||||
// options - start
|
// options - start
|
||||||
changeSelectedDateFromBtn(isNext = false) {
|
changeSelectedDateFromBtn(isNext = false) {
|
||||||
|
if (!this.allDateOfActivityArray || this.allDateOfActivityArray.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const idx = this.allDateOfActivityArray.findIndex((date) => date.isSame(this.selectedDate, 'day'));
|
const idx = this.allDateOfActivityArray.findIndex((date) => date.isSame(this.selectedDate, 'day'));
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
if (isNext) {
|
const newIdx = isNext ? idx - 1 : idx + 1;
|
||||||
if (idx - 1 < this.allDateOfActivityArray.length) {
|
|
||||||
this.selectedDate = this.allDateOfActivityArray[idx - 1];
|
if (newIdx >= 0 && newIdx < this.allDateOfActivityArray.length) {
|
||||||
this.reloadData();
|
this.selectedDate = this.allDateOfActivityArray[newIdx];
|
||||||
}
|
|
||||||
} else if (idx + 1 >= 0) {
|
|
||||||
this.selectedDate = this.allDateOfActivityArray[idx + 1];
|
|
||||||
this.reloadData();
|
this.reloadData();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.selectedDate = isNext
|
||||||
|
? this.allDateOfActivityArray[this.allDateOfActivityArray.length - 1]
|
||||||
|
: this.allDateOfActivityArray[0];
|
||||||
|
this.reloadData();
|
||||||
},
|
},
|
||||||
getDatePickerDisabledDate(time) {
|
getDatePickerDisabledDate(time) {
|
||||||
if (
|
if (
|
||||||
@@ -730,7 +736,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting && this.$refs.activityDetailChartRef[index]) {
|
||||||
this.$refs.activityDetailChartRef[index].initEcharts();
|
this.$refs.activityDetailChartRef[index].initEcharts();
|
||||||
this.intersectionObservers[index].unobserve(entry.target);
|
this.intersectionObservers[index].unobserve(entry.target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,8 +105,7 @@
|
|||||||
methods: {
|
methods: {
|
||||||
async initEcharts(isFirstLoad = false) {
|
async initEcharts(isFirstLoad = false) {
|
||||||
if (!this.echarts) {
|
if (!this.echarts) {
|
||||||
const module = await utils.loadEcharts();
|
this.echarts = await utils.loadEcharts();
|
||||||
this.echarts = module;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const chartsHeight = this.activityDetailData.length * (this.barWidth + 10) + 200;
|
const chartsHeight = this.activityDetailData.length * (this.barWidth + 10) + 200;
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="$emit('click')">
|
||||||
|
<div class="x-friend-item">
|
||||||
|
<template v-if="isLocalFavorite ? favorite.name : favorite.ref">
|
||||||
|
<div class="avatar">
|
||||||
|
<img v-lazy="localFavFakeRef.thumbnailImageUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span class="name" v-text="localFavFakeRef.name"></span>
|
||||||
|
<span class="extra" v-text="localFavFakeRef.authorName"></span>
|
||||||
|
</div>
|
||||||
|
<template v-if="editFavoritesMode">
|
||||||
|
<el-dropdown trigger="click" size="mini" style="margin-left: 5px" @click.native.stop>
|
||||||
|
<el-tooltip placement="top" :content="tooltipContent" :disabled="hideTooltips">
|
||||||
|
<el-button type="default" icon="el-icon-back" size="mini" circle></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<template
|
||||||
|
v-for="groupAPI in API.favoriteAvatarGroups"
|
||||||
|
v-if="isLocalFavorite || groupAPI.name !== group.name">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="groupAPI.name"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
:disabled="groupAPI.count >= groupAPI.capacity"
|
||||||
|
@click.native="handleDropdownItemClick(groupAPI)">
|
||||||
|
{{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-button v-if="!isLocalFavorite" type="text" size="mini" style="margin-left: 5px" @click.stop>
|
||||||
|
<el-checkbox v-model="isSelected"></el-checkbox>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="!isLocalFavorite">
|
||||||
|
<el-tooltip
|
||||||
|
v-if="favorite.deleted"
|
||||||
|
placement="left"
|
||||||
|
:content="$t('view.favorite.unavailable_tooltip')">
|
||||||
|
<i class="el-icon-warning" style="color: #f56c6c; margin-left: 5px"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="favorite.ref.releaseStatus === 'private'"
|
||||||
|
placement="left"
|
||||||
|
:content="$t('view.favorite.private')">
|
||||||
|
<i class="el-icon-warning" style="color: #e6a23c; margin-left: 5px"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="favorite.ref.releaseStatus !== 'private' && !favorite.deleted"
|
||||||
|
placement="left"
|
||||||
|
:content="$t('view.favorite.select_avatar_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
:disabled="API.currentUser.currentAvatar === favorite.id"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-check"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="selectAvatarWithConfirmation"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
placement="right"
|
||||||
|
:content="$t('view.favorite.unfavorite_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
v-if="shiftHeld"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-close"
|
||||||
|
circle
|
||||||
|
style="color: #f56c6c; margin-left: 5px"
|
||||||
|
@click.stop="deleteFavorite(favorite.id)"></el-button>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
type="default"
|
||||||
|
icon="el-icon-star-on"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="showFavoriteDialog"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-tooltip
|
||||||
|
placement="left"
|
||||||
|
:content="$t('view.favorite.select_avatar_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
:disabled="API.currentUser.currentAvatar === favorite.id"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
icon="el-icon-check"
|
||||||
|
@click.stop="selectAvatarWithConfirmation" />
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<el-tooltip
|
||||||
|
v-if="isLocalFavorite"
|
||||||
|
placement="right"
|
||||||
|
:content="$t('view.favorite.unfavorite_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
v-if="shiftHeld"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-close"
|
||||||
|
circle
|
||||||
|
style="color: #f56c6c; margin-left: 5px"
|
||||||
|
@click.stop="removeLocalAvatarFavorite" />
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
type="default"
|
||||||
|
icon="el-icon-star-on"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="showFavoriteDialog"
|
||||||
|
/></el-tooltip>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="avatar"></div>
|
||||||
|
<div class="detail">
|
||||||
|
<span class="name" v-text="favorite.name || favorite.id"></span>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-close"
|
||||||
|
size="mini"
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="deleteFavorite(favorite.id)"></el-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { favoriteRequest } from '../../classes/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FavoritesAvatarItem',
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
favorite: Object,
|
||||||
|
group: [Object, String],
|
||||||
|
editFavoritesMode: Boolean,
|
||||||
|
shiftHeld: Boolean,
|
||||||
|
hideTooltips: Boolean,
|
||||||
|
isLocalFavorite: Boolean
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isSelected: {
|
||||||
|
get() {
|
||||||
|
return this.favorite.$selected;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('handle-select', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
localFavFakeRef() {
|
||||||
|
// local favorite no "ref" property
|
||||||
|
return this.isLocalFavorite ? this.favorite : this.favorite.ref;
|
||||||
|
},
|
||||||
|
|
||||||
|
tooltipContent() {
|
||||||
|
return $t(this.isLocalFavorite ? 'view.favorite.copy_tooltip' : 'view.favorite.move_tooltip');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
moveFavorite(ref, group, type) {
|
||||||
|
favoriteRequest
|
||||||
|
.deleteFavorite({
|
||||||
|
objectId: ref.id
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
favoriteRequest.addFavorite({
|
||||||
|
type,
|
||||||
|
favoriteId: ref.id,
|
||||||
|
tags: group.name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectAvatarWithConfirmation() {
|
||||||
|
this.$emit('select-avatar-with-confirmation', this.favorite.id);
|
||||||
|
},
|
||||||
|
deleteFavorite(objectId) {
|
||||||
|
favoriteRequest.deleteFavorite({
|
||||||
|
objectId
|
||||||
|
});
|
||||||
|
// FIXME: 메시지 수정
|
||||||
|
// this.$confirm('Continue? Delete Favorite', 'Confirm', {
|
||||||
|
// confirmButtonText: 'Confirm',
|
||||||
|
// cancelButtonText: 'Cancel',
|
||||||
|
// type: 'info',
|
||||||
|
// callback: (action) => {
|
||||||
|
// if (action === 'confirm') {
|
||||||
|
// API.deleteFavorite({
|
||||||
|
// objectId
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
addFavoriteAvatar(groupAPI) {
|
||||||
|
return favoriteRequest
|
||||||
|
.addFavorite({
|
||||||
|
type: 'avatar',
|
||||||
|
favoriteId: this.favorite.id,
|
||||||
|
tags: groupAPI.name
|
||||||
|
})
|
||||||
|
.then((args) => {
|
||||||
|
this.$message({
|
||||||
|
message: 'Avatar added to favorites',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
|
||||||
|
return args;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDropdownItemClick(groupAPI) {
|
||||||
|
if (this.isLocalFavorite) {
|
||||||
|
this.addFavoriteAvatar(groupAPI);
|
||||||
|
} else {
|
||||||
|
this.moveFavorite(this.favorite.ref, groupAPI, 'avatar');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showFavoriteDialog() {
|
||||||
|
this.$emit('show-favorite-dialog', 'avatar', this.favorite.id);
|
||||||
|
},
|
||||||
|
removeLocalAvatarFavorite() {
|
||||||
|
this.$emit('remove-local-avatar-favorite', this.favorite.id, this.group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="$emit('click')">
|
||||||
|
<div class="x-friend-item">
|
||||||
|
<div class="avatar">
|
||||||
|
<img v-lazy="favorite.thumbnailImageUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span class="name" v-text="favorite.name"></span>
|
||||||
|
<span class="extra" v-text="favorite.authorName"></span>
|
||||||
|
</div>
|
||||||
|
<el-tooltip placement="left" :content="$t('view.favorite.select_avatar_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
:disabled="API.currentUser.currentAvatar === favorite.id"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-check"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="selectAvatarWithConfirmation"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<template v-if="API.cachedFavoritesByObjectId.has(favorite.id)">
|
||||||
|
<el-tooltip placement="right" content="Unfavorite" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
type="default"
|
||||||
|
icon="el-icon-star-on"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="showFavoriteDialog('avatar', favorite.id)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-tooltip placement="right" content="Favorite" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
type="default"
|
||||||
|
icon="el-icon-star-off"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="showFavoriteDialog('avatar', favorite.id)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FavoritesAvatarLocalHistoryItem',
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
favorite: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
hideTooltips: Boolean
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selectAvatarWithConfirmation() {
|
||||||
|
this.$emit('select-avatar-with-confirmation', this.favorite.id);
|
||||||
|
},
|
||||||
|
showFavoriteDialog() {
|
||||||
|
this.$emit('show-favorite-dialog', 'avatar', this.favorite.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||||
|
<div>
|
||||||
|
<el-button size="small" @click="showAvatarExportDialog">
|
||||||
|
{{ $t('view.favorite.export') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button size="small" style="margin-left: 5px" @click="showAvatarImportDialog">
|
||||||
|
{{ $t('view.favorite.import') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; align-items: center; font-size: 13px; margin-right: 10px">
|
||||||
|
<span class="name" style="margin-right: 5px; line-height: 10px">
|
||||||
|
{{ $t('view.favorite.sort_by') }}
|
||||||
|
</span>
|
||||||
|
<el-radio-group v-model="sortFav" style="margin-right: 12px" @change="saveSortFavoritesOption">
|
||||||
|
<el-radio :label="false">
|
||||||
|
{{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }}
|
||||||
|
</el-radio>
|
||||||
|
<el-radio :label="true">
|
||||||
|
{{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-input
|
||||||
|
v-model="avatarFavoriteSearch"
|
||||||
|
clearable
|
||||||
|
size="mini"
|
||||||
|
:placeholder="$t('view.favorite.avatars.search')"
|
||||||
|
style="width: 200px"
|
||||||
|
@input="searchAvatarFavorites" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="x-friend-list" style="margin-top: 10px">
|
||||||
|
<div
|
||||||
|
v-for="favorite in avatarFavoriteSearchResults"
|
||||||
|
:key="favorite.id"
|
||||||
|
style="display: inline-block; width: 300px; margin-right: 15px"
|
||||||
|
@click="showAvatarDialog(favorite.id)">
|
||||||
|
<div class="x-friend-item">
|
||||||
|
<template v-if="favorite.name">
|
||||||
|
<div class="avatar">
|
||||||
|
<img v-lazy="favorite.thumbnailImageUrl" />
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span class="name" v-text="favorite.name" />
|
||||||
|
<span class="extra" v-text="favorite.authorName" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="avatar"></div>
|
||||||
|
<div class="detail">
|
||||||
|
<span class="name" v-text="favorite.id" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span style="display: block; margin-top: 20px">
|
||||||
|
{{ $t('view.favorite.avatars.vrchat_favorites') }}
|
||||||
|
</span>
|
||||||
|
<el-collapse style="border: 0">
|
||||||
|
<el-collapse-item v-for="group in API.favoriteAvatarGroups" :key="group.name">
|
||||||
|
<template slot="title">
|
||||||
|
<span style="font-weight: bold; font-size: 14px; margin-left: 10px" v-text="group.displayName" />
|
||||||
|
<span style="color: #909399; font-size: 12px; margin-left: 10px">
|
||||||
|
{{ group.count }}/{{ group.capacity }}
|
||||||
|
</span>
|
||||||
|
<el-tooltip placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
circle
|
||||||
|
style="margin-left: 10px"
|
||||||
|
@click.stop="changeFavoriteGroupName(group)" />
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="clearFavoriteGroup(group)" />
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div v-if="group.count" class="x-friend-list" style="margin-top: 10px">
|
||||||
|
<favorites-avatar-item
|
||||||
|
v-for="favorite in groupedByGroupKeyFavoriteAvatars[group.key]"
|
||||||
|
:key="favorite.id"
|
||||||
|
:favorite="favorite"
|
||||||
|
:group="group"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
:shift-held="shiftHeld"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
style="display: inline-block; width: 300px; margin-right: 15px"
|
||||||
|
@handle-select="favorite.$selected = $event"
|
||||||
|
@show-favorite-dialog="showFavoriteDialog"
|
||||||
|
@remove-local-avatar-favorite="removeLocalAvatarFavorite"
|
||||||
|
@select-avatar-with-confirmation="selectAvatarWithConfirmation"
|
||||||
|
@click="showAvatarDialog(favorite.id)" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
style="
|
||||||
|
padding-top: 25px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: rgb(144, 147, 153);
|
||||||
|
">
|
||||||
|
<span>No Data</span>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item>
|
||||||
|
<template slot="title">
|
||||||
|
<span style="font-weight: bold; font-size: 14px; margin-left: 10px">Local History</span>
|
||||||
|
<span style="color: #909399; font-size: 12px; margin-left: 10px"
|
||||||
|
>{{ avatarHistoryArray.length }}/100</span
|
||||||
|
>
|
||||||
|
<el-tooltip placement="right" content="Clear" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="promptClearAvatarHistory"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div v-if="avatarHistoryArray.length" class="x-friend-list" style="margin-top: 10px">
|
||||||
|
<favorites-avatar-local-history-item
|
||||||
|
v-for="favorite in avatarHistoryArray"
|
||||||
|
:key="favorite.id"
|
||||||
|
style="display: inline-block; width: 300px; margin-right: 15px"
|
||||||
|
:favorite="favorite"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
@select-avatar-with-confirmation="selectAvatarWithConfirmation"
|
||||||
|
@show-favorite-dialog="showFavoriteDialog"
|
||||||
|
@click="showAvatarDialog(favorite.id)"></favorites-avatar-local-history-item>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
style="
|
||||||
|
padding-top: 25px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: rgb(144, 147, 153);
|
||||||
|
">
|
||||||
|
<span>No Data</span>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
<span style="display: block; margin-top: 20px">{{ $t('view.favorite.avatars.local_favorites') }}</span>
|
||||||
|
<br />
|
||||||
|
<el-button size="small" :disabled="!isLocalUserVrcplusSupporter" @click="promptNewLocalAvatarFavoriteGroup">
|
||||||
|
{{ $t('view.favorite.avatars.new_group') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="!refreshingLocalFavorites"
|
||||||
|
size="small"
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click="refreshLocalAvatarFavorites">
|
||||||
|
{{ $t('view.favorite.avatars.refresh') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button v-else size="small" style="margin-left: 5px" @click="refreshingLocalFavorites = false">
|
||||||
|
<i class="el-icon-loading" style="margin-right: 5px"></i>
|
||||||
|
<span>{{ $t('view.favorite.avatars.cancel_refresh') }}</span>
|
||||||
|
</el-button>
|
||||||
|
<el-collapse-item
|
||||||
|
v-for="group in localAvatarFavoriteGroups"
|
||||||
|
v-if="localAvatarFavorites[group]"
|
||||||
|
:key="group">
|
||||||
|
<template slot="title">
|
||||||
|
<span :style="{ fontWeight: 'bold', fontSize: '14px', marginLeft: '10px' }">{{ group }}</span>
|
||||||
|
<span :style="{ color: '#909399', fontSize: '12px', marginLeft: '10px' }">{{
|
||||||
|
getLocalAvatarFavoriteGroupLength(group)
|
||||||
|
}}</span>
|
||||||
|
<el-tooltip placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
circle
|
||||||
|
:style="{ marginLeft: '5px' }"
|
||||||
|
@click.stop="promptLocalAvatarFavoriteGroupRename(group)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip
|
||||||
|
placement="right"
|
||||||
|
:content="$t('view.favorite.delete_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
:style="{ marginLeft: '5px' }"
|
||||||
|
@click.stop="promptLocalAvatarFavoriteGroupDelete(group)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div v-if="localAvatarFavorites[group].length" class="x-friend-list" :style="{ marginTop: '10px' }">
|
||||||
|
<favorites-avatar-item
|
||||||
|
v-for="favorite in localAvatarFavorites[group]"
|
||||||
|
:key="favorite.id"
|
||||||
|
is-local-favorite
|
||||||
|
:style="{ display: 'inline-block', width: '300px', marginRight: '15px' }"
|
||||||
|
:favorite="favorite"
|
||||||
|
:group="group"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
:shift-held="shiftHeld"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
@handle-select="favorite.$selected = $event"
|
||||||
|
@show-favorite-dialog="showFavoriteDialog"
|
||||||
|
@remove-local-avatar-favorite="removeLocalAvatarFavorite"
|
||||||
|
@select-avatar-with-confirmation="selectAvatarWithConfirmation"
|
||||||
|
@click="showAvatarDialog(favorite.id)"></favorites-avatar-item>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
:style="{
|
||||||
|
paddingTop: '25px',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
color: 'rgb(144, 147, 153)'
|
||||||
|
}">
|
||||||
|
<span>No Data</span>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
<avatar-export-dialog
|
||||||
|
:avatar-export-dialog-visible.sync="avatarExportDialogVisible"
|
||||||
|
:favorite-avatars="favoriteAvatars"
|
||||||
|
:local-avatar-favorite-groups="localAvatarFavoriteGroups"
|
||||||
|
:local-avatar-favorites="localAvatarFavorites"
|
||||||
|
:local-avatar-favorites-list="localAvatarFavoritesList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FavoritesAvatarItem from './FavoritesAvatarItem.vue';
|
||||||
|
import FavoritesAvatarLocalHistoryItem from './FavoritesAvatarLocalHistoryItem.vue';
|
||||||
|
import AvatarExportDialog from '../../views/dialogs/AvatarExportDialog.vue';
|
||||||
|
import { favoriteRequest } from '../../classes/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FavoritesAvatarTab',
|
||||||
|
components: { FavoritesAvatarItem, FavoritesAvatarLocalHistoryItem, AvatarExportDialog },
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
sortFavorites: Boolean,
|
||||||
|
hideTooltips: Boolean,
|
||||||
|
shiftHeld: Boolean,
|
||||||
|
editFavoritesMode: Boolean,
|
||||||
|
avatarHistoryArray: Array,
|
||||||
|
refreshingLocalFavorites: Boolean,
|
||||||
|
localAvatarFavoriteGroups: Array,
|
||||||
|
localAvatarFavorites: Object,
|
||||||
|
favoriteAvatars: Array,
|
||||||
|
localAvatarFavoritesList: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
avatarExportDialogVisible: false,
|
||||||
|
avatarFavoriteSearch: '',
|
||||||
|
avatarFavoriteSearchResults: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
sortFav: {
|
||||||
|
get() {
|
||||||
|
return this.sortFavorites;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:sort-favorites', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
groupedByGroupKeyFavoriteAvatars() {
|
||||||
|
const groupedByGroupKeyFavoriteAvatars = {};
|
||||||
|
this.favoriteAvatars.forEach((avatar) => {
|
||||||
|
if (avatar.groupKey) {
|
||||||
|
if (!groupedByGroupKeyFavoriteAvatars[avatar.groupKey]) {
|
||||||
|
groupedByGroupKeyFavoriteAvatars[avatar.groupKey] = [];
|
||||||
|
}
|
||||||
|
groupedByGroupKeyFavoriteAvatars[avatar.groupKey].push(avatar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return groupedByGroupKeyFavoriteAvatars;
|
||||||
|
},
|
||||||
|
isLocalUserVrcplusSupporter() {
|
||||||
|
return this.API.currentUser.$isVRCPlus;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getLocalAvatarFavoriteGroupLength(group) {
|
||||||
|
const favoriteGroup = this.localAvatarFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return favoriteGroup.length;
|
||||||
|
},
|
||||||
|
searchAvatarFavorites() {
|
||||||
|
let ref = null;
|
||||||
|
const search = this.avatarFavoriteSearch.toLowerCase();
|
||||||
|
if (search.length < 3) {
|
||||||
|
this.avatarFavoriteSearchResults = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
for (let i = 0; i < this.localAvatarFavoriteGroups.length; ++i) {
|
||||||
|
const group = this.localAvatarFavoriteGroups[i];
|
||||||
|
if (!this.localAvatarFavorites[group]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let j = 0; j < this.localAvatarFavorites[group].length; ++j) {
|
||||||
|
ref = this.localAvatarFavorites[group][j];
|
||||||
|
if (!ref || !ref.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
||||||
|
if (!results.some((r) => r.id === ref.id)) {
|
||||||
|
results.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.favoriteAvatars.length; ++i) {
|
||||||
|
ref = this.favoriteAvatars[i].ref;
|
||||||
|
if (!ref) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
||||||
|
if (!results.some((r) => r.id === ref.id)) {
|
||||||
|
results.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.avatarFavoriteSearchResults = results;
|
||||||
|
},
|
||||||
|
clearFavoriteGroup(ctx) {
|
||||||
|
// FIXME: 메시지 수정
|
||||||
|
this.$confirm('Continue? Clear Group', 'Confirm', {
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
type: 'info',
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
favoriteRequest.clearFavoriteGroup({
|
||||||
|
type: ctx.type,
|
||||||
|
group: ctx.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showAvatarExportDialog() {
|
||||||
|
this.avatarExportDialogVisible = true;
|
||||||
|
},
|
||||||
|
showAvatarImportDialog() {
|
||||||
|
this.$emit('show-avatar-import-dialog');
|
||||||
|
},
|
||||||
|
saveSortFavoritesOption() {
|
||||||
|
this.$emit('save-sort-favorites-option');
|
||||||
|
},
|
||||||
|
showAvatarDialog(id) {
|
||||||
|
this.$emit('show-avatar-dialog', id);
|
||||||
|
},
|
||||||
|
changeFavoriteGroupName(group) {
|
||||||
|
this.$emit('change-favorite-group-name', group);
|
||||||
|
},
|
||||||
|
showFavoriteDialog(type, id) {
|
||||||
|
this.$emit('show-favorite-dialog', type, id);
|
||||||
|
},
|
||||||
|
removeLocalAvatarFavorite(id, group) {
|
||||||
|
this.$emit('remove-local-avatar-favorite', id, group);
|
||||||
|
},
|
||||||
|
selectAvatarWithConfirmation(id) {
|
||||||
|
this.$emit('select-avatar-with-confirmation', id);
|
||||||
|
},
|
||||||
|
promptClearAvatarHistory() {
|
||||||
|
this.$emit('prompt-clear-avatar-history');
|
||||||
|
},
|
||||||
|
promptNewLocalAvatarFavoriteGroup() {
|
||||||
|
this.$emit('prompt-new-local-avatar-favorite-group');
|
||||||
|
},
|
||||||
|
refreshLocalAvatarFavorites() {
|
||||||
|
this.$emit('refresh-local-avatar-favorites');
|
||||||
|
},
|
||||||
|
promptLocalAvatarFavoriteGroupRename(group) {
|
||||||
|
this.$emit('prompt-local-avatar-favorite-group-rename', group);
|
||||||
|
},
|
||||||
|
promptLocalAvatarFavoriteGroupDelete(group) {
|
||||||
|
this.$emit('prompt-local-avatar-favorite-group-delete', group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="$emit('click')">
|
||||||
|
<div class="x-friend-item">
|
||||||
|
<template v-if="favorite.ref">
|
||||||
|
<div class="avatar" :class="userStatusClass(favorite.ref)">
|
||||||
|
<img v-lazy="userImage(favorite.ref)" />
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
:style="{ color: favorite.ref.$userColour }"
|
||||||
|
v-text="favorite.ref.displayName"></span>
|
||||||
|
<location
|
||||||
|
class="extra"
|
||||||
|
v-if="favorite.ref.location !== 'offline'"
|
||||||
|
:location="favorite.ref.location"
|
||||||
|
:traveling="favorite.ref.travelingToLocation"
|
||||||
|
:link="false"></location>
|
||||||
|
<span v-else v-text="favorite.ref.statusDescription"></span>
|
||||||
|
</div>
|
||||||
|
<template v-if="editFavoritesMode">
|
||||||
|
<el-dropdown trigger="click" size="mini" style="margin-left: 5px" @click.native.stop>
|
||||||
|
<el-tooltip
|
||||||
|
placement="left"
|
||||||
|
:content="$t('view.favorite.move_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button type="default" icon="el-icon-back" size="mini" circle></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<template v-for="groupAPI in API.favoriteFriendGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
v-if="groupAPI.name !== group.name"
|
||||||
|
:key="groupAPI.name"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
:disabled="groupAPI.count >= groupAPI.capacity"
|
||||||
|
@click.native="moveFavorite(favorite.ref, groupAPI, 'friend')">
|
||||||
|
{{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-button type="text" size="mini" style="margin-left: 5px" @click.stop>
|
||||||
|
<el-checkbox v-model="favorite.$selected"></el-checkbox>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-tooltip
|
||||||
|
placement="right"
|
||||||
|
:content="$t('view.favorite.unfavorite_tooltip')"
|
||||||
|
:disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
v-if="shiftHeld"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-close"
|
||||||
|
circle
|
||||||
|
style="color: #f56c6c; margin-left: 5px"
|
||||||
|
@click.stop="deleteFavorite(favorite.id)"></el-button>
|
||||||
|
<el-button
|
||||||
|
v-else
|
||||||
|
type="default"
|
||||||
|
icon="el-icon-star-on"
|
||||||
|
size="mini"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="showFavoriteDialog('friend', favorite.id)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div class="avatar"></div>
|
||||||
|
<div class="detail">
|
||||||
|
<span v-text="favorite.name || favorite.id"></span>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-close"
|
||||||
|
size="mini"
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="deleteFavorite(favorite.id)"></el-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Location from '../common/Location.vue';
|
||||||
|
import { favoriteRequest } from '../../classes/request';
|
||||||
|
export default {
|
||||||
|
components: { Location },
|
||||||
|
inject: ['showUserDialog', 'userImage', 'userStatusClass', 'API'],
|
||||||
|
props: {
|
||||||
|
favorite: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
hideTooltips: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
shiftHeld: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
editFavoritesMode: Boolean
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
moveFavorite(ref, group, type) {
|
||||||
|
favoriteRequest
|
||||||
|
.deleteFavorite({
|
||||||
|
objectId: ref.id
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
favoriteRequest.addFavorite({
|
||||||
|
type,
|
||||||
|
favoriteId: ref.id,
|
||||||
|
tags: group.name
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deleteFavorite(objectId) {
|
||||||
|
favoriteRequest.deleteFavorite({
|
||||||
|
objectId
|
||||||
|
});
|
||||||
|
// FIXME: 메시지 수정
|
||||||
|
// this.$confirm('Continue? Delete Favorite', 'Confirm', {
|
||||||
|
// confirmButtonText: 'Confirm',
|
||||||
|
// cancelButtonText: 'Cancel',
|
||||||
|
// type: 'info',
|
||||||
|
// callback: (action) => {
|
||||||
|
// if (action === 'confirm') {
|
||||||
|
// API.deleteFavorite({
|
||||||
|
// objectId
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
showFavoriteDialog(param1, param2) {
|
||||||
|
this.$emit('show-favorite-dialog', param1, param2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||||
|
<div>
|
||||||
|
<el-button size="small" @click="showFriendExportDialog">{{ $t('view.favorite.export') }}</el-button>
|
||||||
|
<el-button size="small" style="margin-left: 5px" @click="showFriendImportDialog">{{
|
||||||
|
$t('view.favorite.import')
|
||||||
|
}}</el-button>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; align-items: center; font-size: 13px; margin-right: 10px">
|
||||||
|
<span class="name" style="margin-right: 5px; line-height: 10px">{{ $t('view.favorite.sort_by') }}</span>
|
||||||
|
<el-radio-group v-model="sortFav" @change="saveSortFavoritesOption">
|
||||||
|
<el-radio :label="false">{{
|
||||||
|
$t('view.settings.appearance.appearance.sort_favorite_by_name')
|
||||||
|
}}</el-radio>
|
||||||
|
<el-radio :label="true">{{
|
||||||
|
$t('view.settings.appearance.appearance.sort_favorite_by_date')
|
||||||
|
}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span style="display: block; margin-top: 30px">{{ $t('view.favorite.avatars.vrchat_favorites') }}</span>
|
||||||
|
<el-collapse style="border: 0">
|
||||||
|
<el-collapse-item v-for="group in API.favoriteFriendGroups" :key="group.name">
|
||||||
|
<template slot="title">
|
||||||
|
<span
|
||||||
|
style="font-weight: bold; font-size: 14px; margin-left: 10px"
|
||||||
|
v-text="group.displayName"></span>
|
||||||
|
<span style="color: #909399; font-size: 12px; margin-left: 10px"
|
||||||
|
>{{ group.count }}/{{ group.capacity }}</span
|
||||||
|
>
|
||||||
|
<el-tooltip placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-edit"
|
||||||
|
circle
|
||||||
|
style="margin-left: 10px"
|
||||||
|
@click.stop="changeFavoriteGroupName(group)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
<el-tooltip placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
style="margin-left: 5px"
|
||||||
|
@click.stop="clearFavoriteGroup(group)"></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
<div v-if="group.count" class="x-friend-list" style="margin-top: 10px">
|
||||||
|
<favorites-friend-item
|
||||||
|
v-for="favorite in groupedByGroupKeyFavoriteFriends[group.key]"
|
||||||
|
:key="favorite.id"
|
||||||
|
style="display: inline-block; width: 300px; margin-right: 15px"
|
||||||
|
:favorite="favorite"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
:group="group"
|
||||||
|
@click="showUserDialog(favorite.id)" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
style="
|
||||||
|
padding-top: 25px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: rgb(144, 147, 153);
|
||||||
|
">
|
||||||
|
<span>No Data</span>
|
||||||
|
</div>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
<friend-export-dialog
|
||||||
|
:friend-export-dialog-visible.sync="friendExportDialogVisible"
|
||||||
|
:favorite-friends="favoriteFriends"></friend-export-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FavoritesFriendItem from './FavoritesFriendItem.vue';
|
||||||
|
import FriendExportDialog from '../../views/dialogs/FriendExportDialog.vue';
|
||||||
|
import { favoriteRequest } from '../../classes/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FavoritesFriendTab',
|
||||||
|
components: { FriendExportDialog, FavoritesFriendItem },
|
||||||
|
inject: ['showUserDialog', 'API'],
|
||||||
|
props: {
|
||||||
|
favoriteFriends: Array,
|
||||||
|
sortFavorites: Boolean,
|
||||||
|
hideTooltips: Boolean,
|
||||||
|
groupedByGroupKeyFavoriteFriends: Object,
|
||||||
|
editFavoritesMode: Boolean
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
friendExportDialogVisible: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
sortFav: {
|
||||||
|
get() {
|
||||||
|
return this.sortFavorites;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:sort-favorites', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showFriendExportDialog() {
|
||||||
|
this.friendExportDialogVisible = true;
|
||||||
|
},
|
||||||
|
showFriendImportDialog() {
|
||||||
|
this.$emit('show-friend-import-dialog');
|
||||||
|
},
|
||||||
|
saveSortFavoritesOption() {
|
||||||
|
this.$emit('save-sort-favorites-option');
|
||||||
|
},
|
||||||
|
|
||||||
|
clearFavoriteGroup(ctx) {
|
||||||
|
// FIXME: 메시지 수정
|
||||||
|
this.$confirm('Continue? Clear Group', 'Confirm', {
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
type: 'info',
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
favoriteRequest.clearFavoriteGroup({
|
||||||
|
type: ctx.type,
|
||||||
|
group: ctx.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
changeFavoriteGroupName(group) {
|
||||||
|
this.$emit('change-favorite-group-name', group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||||
<div>
|
<div>
|
||||||
<el-button size="small" @click="$emit('show-world-export-dialog')">{{
|
<el-button size="small" @click="showExportDialog">{{ $t('view.favorite.export') }}</el-button>
|
||||||
$t('view.favorite.export')
|
|
||||||
}}</el-button>
|
|
||||||
<el-button size="small" style="margin-left: 5px" @click="$emit('show-world-import-dialog')">{{
|
<el-button size="small" style="margin-left: 5px" @click="$emit('show-world-import-dialog')">{{
|
||||||
$t('view.favorite.import')
|
$t('view.favorite.import')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
@@ -103,7 +101,7 @@
|
|||||||
icon="el-icon-edit"
|
icon="el-icon-edit"
|
||||||
circle
|
circle
|
||||||
style="margin-left: 5px"
|
style="margin-left: 5px"
|
||||||
@click.stop="$emit('change-favorite-group-name', group)" />
|
@click.stop="changeFavoriteGroupName(group)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
placement="right"
|
placement="right"
|
||||||
@@ -114,7 +112,7 @@
|
|||||||
icon="el-icon-delete"
|
icon="el-icon-delete"
|
||||||
circle
|
circle
|
||||||
style="margin-left: 5px"
|
style="margin-left: 5px"
|
||||||
@click.stop="$emit('clear-favorite-group', group)" />
|
@click.stop="clearFavoriteGroup(group)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
@@ -219,41 +217,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
|
<world-export-dialog
|
||||||
|
:favorite-worlds="favoriteWorlds"
|
||||||
|
:world-export-dialog-visible.sync="worldExportDialogVisible"
|
||||||
|
:local-world-favorites="localWorldFavorites"
|
||||||
|
:local-world-favorite-groups="localWorldFavoriteGroups"
|
||||||
|
:local-world-favorites-list="localWorldFavoritesList" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FavoritesWorldItem from './FavoritesWorldItem.vue';
|
import FavoritesWorldItem from './FavoritesWorldItem.vue';
|
||||||
|
import WorldExportDialog from '../../views/dialogs/WorldExportDialog.vue';
|
||||||
import { favoriteRequest } from '../../classes/request';
|
import { favoriteRequest } from '../../classes/request';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FavoritesWorldTab',
|
name: 'FavoritesWorldTab',
|
||||||
components: {
|
components: {
|
||||||
FavoritesWorldItem
|
FavoritesWorldItem,
|
||||||
|
WorldExportDialog
|
||||||
},
|
},
|
||||||
inject: ['API'],
|
inject: ['API'],
|
||||||
props: {
|
props: {
|
||||||
sortFavorites: Boolean,
|
sortFavorites: Boolean,
|
||||||
worldFavoriteSearchResults: Array,
|
|
||||||
|
|
||||||
hideTooltips: Boolean,
|
hideTooltips: Boolean,
|
||||||
|
|
||||||
favoriteWorlds: Array,
|
favoriteWorlds: Array,
|
||||||
|
|
||||||
editFavoritesMode: Boolean,
|
editFavoritesMode: Boolean,
|
||||||
shiftHeld: Boolean,
|
shiftHeld: Boolean,
|
||||||
|
|
||||||
refreshingLocalFavorites: Boolean,
|
refreshingLocalFavorites: Boolean,
|
||||||
|
|
||||||
localWorldFavoriteGroups: Array,
|
localWorldFavoriteGroups: Array,
|
||||||
localWorldFavorites: Object
|
localWorldFavorites: Object,
|
||||||
|
localWorldFavoritesList: Array
|
||||||
// removeLocalWorldFavorite: Function
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
worldGroupVisibilityOptions: ['private', 'friends', 'public'],
|
worldGroupVisibilityOptions: ['private', 'friends', 'public'],
|
||||||
worldFavoriteSearch: ''
|
worldFavoriteSearch: '',
|
||||||
|
worldExportDialogVisible: false,
|
||||||
|
worldFavoriteSearchResults: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -281,6 +282,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showExportDialog() {
|
||||||
|
this.worldExportDialogVisible = true;
|
||||||
|
},
|
||||||
|
|
||||||
userFavoriteWorldsStatusForFavTab(visibility) {
|
userFavoriteWorldsStatusForFavTab(visibility) {
|
||||||
let style = '';
|
let style = '';
|
||||||
if (visibility === 'public') {
|
if (visibility === 'public') {
|
||||||
@@ -318,7 +323,7 @@
|
|||||||
inputErrorMessage: $t('prompt.new_local_favorite_group.input_error'),
|
inputErrorMessage: $t('prompt.new_local_favorite_group.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
this.newLocalWorldFavoriteGroup(instance.inputValue);
|
this.$emit('new-local-world-favorite-group', instance.inputValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,7 +342,7 @@
|
|||||||
inputValue: group,
|
inputValue: group,
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
this.renameLocalWorldFavoriteGroup(instance.inputValue, group);
|
this.$emit('rename-local-world-favorite-group', instance.inputValue, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,9 +360,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
searchWorldFavorites() {
|
|
||||||
this.$emit('search-world-favorites', this.worldFavoriteSearch);
|
|
||||||
},
|
|
||||||
getLocalWorldFavoriteGroupLength(group) {
|
getLocalWorldFavoriteGroupLength(group) {
|
||||||
const favoriteGroup = this.localWorldFavorites[group];
|
const favoriteGroup = this.localWorldFavorites[group];
|
||||||
if (!favoriteGroup) {
|
if (!favoriteGroup) {
|
||||||
@@ -365,6 +367,67 @@
|
|||||||
}
|
}
|
||||||
return favoriteGroup.length;
|
return favoriteGroup.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearFavoriteGroup(ctx) {
|
||||||
|
// FIXME: 메시지 수정
|
||||||
|
this.$confirm('Continue? Clear Group', 'Confirm', {
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
type: 'info',
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
favoriteRequest.clearFavoriteGroup({
|
||||||
|
type: ctx.type,
|
||||||
|
group: ctx.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
searchWorldFavorites(worldFavoriteSearch) {
|
||||||
|
let ref = null;
|
||||||
|
const search = worldFavoriteSearch.toLowerCase();
|
||||||
|
if (search.length < 3) {
|
||||||
|
this.worldFavoriteSearchResults = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
for (let i = 0; i < this.localWorldFavoriteGroups.length; ++i) {
|
||||||
|
const group = this.localWorldFavoriteGroups[i];
|
||||||
|
if (!this.localWorldFavorites[group]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let j = 0; j < this.localWorldFavorites[group].length; ++j) {
|
||||||
|
ref = this.localWorldFavorites[group][j];
|
||||||
|
if (!ref || !ref.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
||||||
|
if (!results.some((r) => r.id === ref.id)) {
|
||||||
|
results.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < this.favoriteWorlds.length; ++i) {
|
||||||
|
ref = this.favoriteWorlds[i].ref;
|
||||||
|
if (!ref) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ref.name.toLowerCase().includes(search) || ref.authorName.toLowerCase().includes(search)) {
|
||||||
|
if (!results.some((r) => r.id === ref.id)) {
|
||||||
|
results.push(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.worldFavoriteSearchResults = results;
|
||||||
|
},
|
||||||
|
changeFavoriteGroupName(group) {
|
||||||
|
this.$emit('change-favorite-group-name', group);
|
||||||
|
},
|
||||||
showWorldDialog(event) {
|
showWorldDialog(event) {
|
||||||
this.$emit('show-world-dialog', event);
|
this.$emit('show-world-dialog', event);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -293,7 +293,7 @@
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const key in vipFriendsByGroup) {
|
for (const key in vipFriendsByGroup) {
|
||||||
if (Object.prototype.hasOwnProperty.call(vipFriendsByGroup, key)) {
|
if (Object.hasOwn(vipFriendsByGroup, key)) {
|
||||||
const groupFriends = vipFriendsByGroup[key];
|
const groupFriends = vipFriendsByGroup[key];
|
||||||
// sort groupFriends using the order of vipFriends
|
// sort groupFriends using the order of vipFriends
|
||||||
// avoid unnecessary sorting
|
// avoid unnecessary sorting
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ mixin favoritesDialog
|
|||||||
template(v-else)
|
template(v-else)
|
||||||
el-button(
|
el-button(
|
||||||
v-for='group in favoriteDialog.groups'
|
v-for='group in favoriteDialog.groups'
|
||||||
:key='group'
|
:key='group.key'
|
||||||
style='display: block; width: 100%; margin: 10px 0'
|
style='display: block; width: 100%; margin: 10px 0'
|
||||||
@click='addFavorite(group)') {{ group.displayName }} ({{ group.count }} / {{ group.capacity }})
|
@click='addFavorite(group)') {{ group.displayName }} ({{ group.count }} / {{ group.capacity }})
|
||||||
div(v-if='favoriteDialog.visible && favoriteDialog.type === "world"' style='margin-top: 20px')
|
div(v-if='favoriteDialog.visible && favoriteDialog.type === "world"' style='margin-top: 20px')
|
||||||
@@ -99,57 +99,6 @@ mixin favoritesDialog
|
|||||||
style='margin-top: 15px'
|
style='margin-top: 15px'
|
||||||
@click.native='$event.target.tagName === "TEXTAREA" && $event.target.select()')
|
@click.native='$event.target.tagName === "TEXTAREA" && $event.target.select()')
|
||||||
|
|
||||||
//- dialog: export world list
|
|
||||||
el-dialog.x-dialog(
|
|
||||||
:before-close='beforeDialogClose'
|
|
||||||
@mousedown.native='dialogMouseDown'
|
|
||||||
@mouseup.native='dialogMouseUp'
|
|
||||||
ref='worldExportDialogRef'
|
|
||||||
:visible.sync='worldExportDialogVisible'
|
|
||||||
:title='$t("dialog.world_export.header")'
|
|
||||||
width='650px')
|
|
||||||
el-checkbox-group(
|
|
||||||
v-model='exportSelectedOptions'
|
|
||||||
@change='updateWorldExportDialog()'
|
|
||||||
style='margin-bottom: 10px')
|
|
||||||
template(v-for='option in exportSelectOptions')
|
|
||||||
el-checkbox(:key='option.value' :label='option.label')
|
|
||||||
el-dropdown(@click.native.stop trigger='click' size='small')
|
|
||||||
el-button(size='mini')
|
|
||||||
span(v-if='worldExportFavoriteGroup') {{ worldExportFavoriteGroup.displayName }} ({{ worldExportFavoriteGroup.count }}/{{ worldExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectWorldExportGroup(null)') None
|
|
||||||
template(v-for='groupAPI in API.favoriteWorldGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectWorldExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
|
||||||
el-dropdown(@click.native.stop trigger='click' size='small' style='margin-left: 10px')
|
|
||||||
el-button(size='mini')
|
|
||||||
span(v-if='worldExportLocalFavoriteGroup') {{ worldExportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
span(v-else) Select Group #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
el-dropdown-item(
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectWorldExportLocalGroup(null)') None
|
|
||||||
template(v-for='group in localWorldFavoriteGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='group'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectWorldExportLocalGroup(group)') {{ group }} ({{ localWorldFavorites[group].length }})
|
|
||||||
br
|
|
||||||
el-input(
|
|
||||||
type='textarea'
|
|
||||||
v-if='worldExportDialogVisible'
|
|
||||||
v-model='worldExportContent'
|
|
||||||
size='mini'
|
|
||||||
rows='15'
|
|
||||||
resize='none'
|
|
||||||
readonly
|
|
||||||
style='margin-top: 15px'
|
|
||||||
@click.native='handleCopyWorldExportData')
|
|
||||||
|
|
||||||
//- dialog: World import dialog
|
//- dialog: World import dialog
|
||||||
el-dialog.x-dialog(
|
el-dialog.x-dialog(
|
||||||
:before-close='beforeDialogClose'
|
:before-close='beforeDialogClose'
|
||||||
@@ -239,57 +188,6 @@ mixin favoritesDialog
|
|||||||
template(#default='scope')
|
template(#default='scope')
|
||||||
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemWorldImport(scope.row)')
|
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemWorldImport(scope.row)')
|
||||||
|
|
||||||
//- dialog: export avatar list
|
|
||||||
el-dialog.x-dialog(
|
|
||||||
:before-close='beforeDialogClose'
|
|
||||||
@mousedown.native='dialogMouseDown'
|
|
||||||
@mouseup.native='dialogMouseUp'
|
|
||||||
ref='avatarExportDialogRef'
|
|
||||||
:visible.sync='avatarExportDialogVisible'
|
|
||||||
:title='$t("dialog.avatar_export.header")'
|
|
||||||
width='650px')
|
|
||||||
el-checkbox-group(
|
|
||||||
v-model='exportSelectedOptions'
|
|
||||||
@change='updateAvatarExportDialog()'
|
|
||||||
style='margin-bottom: 10px')
|
|
||||||
template(v-for='option in exportSelectOptions')
|
|
||||||
el-checkbox(:key='option.value' :label='option.label')
|
|
||||||
el-dropdown(@click.native.stop trigger='click' size='small')
|
|
||||||
el-button(size='mini')
|
|
||||||
span(v-if='avatarExportFavoriteGroup') {{ avatarExportFavoriteGroup.displayName }} ({{ avatarExportFavoriteGroup.count }}/{{ avatarExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectAvatarExportGroup(null)') All Favorites
|
|
||||||
template(v-for='groupAPI in API.favoriteAvatarGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectAvatarExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
|
||||||
el-dropdown(@click.native.stop trigger='click' size='small' style='margin-left: 10px')
|
|
||||||
el-button(size='mini')
|
|
||||||
span(v-if='avatarExportLocalFavoriteGroup') {{ avatarExportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
span(v-else) Select Group #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
el-dropdown-item(
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectAvatarExportLocalGroup(null)') None
|
|
||||||
template(v-for='group in localAvatarFavoriteGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='group'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectAvatarExportLocalGroup(group)') {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
|
|
||||||
br
|
|
||||||
el-input(
|
|
||||||
type='textarea'
|
|
||||||
v-if='avatarExportDialogVisible'
|
|
||||||
v-model='avatarExportContent'
|
|
||||||
size='mini'
|
|
||||||
rows='15'
|
|
||||||
resize='none'
|
|
||||||
readonly
|
|
||||||
style='margin-top: 15px'
|
|
||||||
@click.native='handleCopyAvatarExportData')
|
|
||||||
|
|
||||||
//- dialog: Avatar import dialog
|
//- dialog: Avatar import dialog
|
||||||
el-dialog.x-dialog(
|
el-dialog.x-dialog(
|
||||||
:before-close='beforeDialogClose'
|
:before-close='beforeDialogClose'
|
||||||
@@ -378,38 +276,6 @@ mixin favoritesDialog
|
|||||||
template(#default='scope')
|
template(#default='scope')
|
||||||
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemAvatarImport(scope.row)')
|
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemAvatarImport(scope.row)')
|
||||||
|
|
||||||
//- dialog: export friend list
|
|
||||||
el-dialog.x-dialog(
|
|
||||||
:before-close='beforeDialogClose'
|
|
||||||
@mousedown.native='dialogMouseDown'
|
|
||||||
@mouseup.native='dialogMouseUp'
|
|
||||||
ref='friendExportDialogRef'
|
|
||||||
:visible.sync='friendExportDialogVisible'
|
|
||||||
:title='$t("dialog.friend_export.header")'
|
|
||||||
width='650px')
|
|
||||||
el-dropdown(@click.native.stop trigger='click' size='small')
|
|
||||||
el-button(size='mini')
|
|
||||||
span(v-if='friendExportFavoriteGroup') {{ friendExportFavoriteGroup.displayName }} ({{ friendExportFavoriteGroup.count }}/{{ friendExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectFriendExportGroup(null)') All Favorites
|
|
||||||
template(v-for='groupAPI in API.favoriteFriendGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='selectFriendExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
|
||||||
br
|
|
||||||
el-input(
|
|
||||||
type='textarea'
|
|
||||||
v-if='friendExportDialogVisible'
|
|
||||||
v-model='friendExportContent'
|
|
||||||
size='mini'
|
|
||||||
rows='15'
|
|
||||||
resize='none'
|
|
||||||
readonly
|
|
||||||
style='margin-top: 15px'
|
|
||||||
@click.native='handleCopyFriendExportData')
|
|
||||||
|
|
||||||
//- dialog: Friend import dialog
|
//- dialog: Friend import dialog
|
||||||
el-dialog.x-dialog(
|
el-dialog.x-dialog(
|
||||||
:before-close='beforeDialogClose'
|
:before-close='beforeDialogClose'
|
||||||
|
|||||||
@@ -1,485 +0,0 @@
|
|||||||
mixin favoritesTab
|
|
||||||
.x-container(v-show='menuActiveIndex === "favorite"')
|
|
||||||
div(style='font-size: 13px; position: absolute; display: flex; right: 0; z-index: 1; margin-right: 15px')
|
|
||||||
div(v-if='editFavoritesMode' style='display: inline-block; margin-right: 10px')
|
|
||||||
el-button(size='small' @click='clearBulkFavoriteSelection') {{ $t('view.favorite.clear') }}
|
|
||||||
el-button(size='small' @click='bulkCopyFavoriteSelection') {{ $t('view.favorite.copy') }}
|
|
||||||
el-button(size='small' @click='showBulkUnfavoriteSelectionConfirm') {{ $t('view.favorite.bulk_unfavorite') }}
|
|
||||||
div(style='display: flex; align-items: center; margin-right: 10px')
|
|
||||||
span.name {{ $t('view.favorite.edit_mode') }}
|
|
||||||
el-switch(v-model='editFavoritesMode' style='margin-left: 5px')
|
|
||||||
el-tooltip(placement='bottom' :content='$t("view.favorite.refresh_tooltip")' :disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
type='default'
|
|
||||||
:loading='API.isFavoriteLoading'
|
|
||||||
@click='API.refreshFavorites(); getLocalWorldFavorites()'
|
|
||||||
size='small'
|
|
||||||
icon='el-icon-refresh'
|
|
||||||
circle)
|
|
||||||
el-tabs(type='card' v-loading='API.isFavoriteLoading' style='height: 100%')
|
|
||||||
el-tab-pane(:label='$t("view.favorite.friends.header")' lazy)
|
|
||||||
div(style='display: flex; align-items: center; justify-content: space-between')
|
|
||||||
div
|
|
||||||
el-button(size='small' @click='showFriendExportDialog') {{ $t('view.favorite.export') }}
|
|
||||||
el-button(size='small' @click='showFriendImportDialog' style='margin-left: 5px') {{ $t('view.favorite.import') }}
|
|
||||||
div(style='display: flex; align-items: center; font-size: 13px; margin-right: 10px')
|
|
||||||
span.name(style='margin-right: 5px; line-height: 10px') {{ $t('view.favorite.sort_by') }}
|
|
||||||
el-radio-group(v-model='sortFavorites' @change='saveSortFavoritesOption')
|
|
||||||
el-radio(:label='false') {{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }}
|
|
||||||
el-radio(:label='true') {{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }}
|
|
||||||
span(style='display: block; margin-top: 30px') {{ $t('view.favorite.avatars.vrchat_favorites') }}
|
|
||||||
el-collapse(style='border: 0')
|
|
||||||
el-collapse-item(v-for='group in API.favoriteFriendGroups' :key='group.name')
|
|
||||||
template(slot='title')
|
|
||||||
span(
|
|
||||||
v-text='group.displayName'
|
|
||||||
style='font-weight: bold; font-size: 14px; margin-left: 10px')
|
|
||||||
span(style='color: #909399; font-size: 12px; margin-left: 10px') {{ group.count }}/{{ group.capacity }}
|
|
||||||
el-tooltip(
|
|
||||||
placement='top'
|
|
||||||
:content='$t("view.favorite.rename_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='changeFavoriteGroupName(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-edit'
|
|
||||||
circle
|
|
||||||
style='margin-left: 10px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.clear_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='clearFavoriteGroup(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-delete'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
.x-friend-list(v-if='group.count' style='margin-top: 10px')
|
|
||||||
div(
|
|
||||||
style='display: inline-block; width: 300px; margin-right: 15px'
|
|
||||||
v-for='favorite in groupedByGroupKeyFavoriteFriends[group.key]'
|
|
||||||
:key='favorite.id'
|
|
||||||
@click='showUserDialog(favorite.id)')
|
|
||||||
.x-friend-item
|
|
||||||
template(v-if='favorite.ref')
|
|
||||||
.avatar(:class='userStatusClass(favorite.ref)')
|
|
||||||
img(v-lazy='userImage(favorite.ref)')
|
|
||||||
.detail
|
|
||||||
span.name(
|
|
||||||
v-text='favorite.ref.displayName'
|
|
||||||
:style='{ color: favorite.ref.$userColour }')
|
|
||||||
location.extra(
|
|
||||||
v-if='favorite.ref.location !== "offline"'
|
|
||||||
:location='favorite.ref.location'
|
|
||||||
:traveling='favorite.ref.travelingToLocation'
|
|
||||||
:link='false')
|
|
||||||
span(v-else v-text='favorite.ref.statusDescription')
|
|
||||||
template(v-if='editFavoritesMode')
|
|
||||||
el-dropdown(
|
|
||||||
trigger='click'
|
|
||||||
@click.native.stop
|
|
||||||
size='mini'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.move_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(type='default' icon='el-icon-back' size='mini' circle)
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
template(
|
|
||||||
v-if='groupAPI.name !== group.name'
|
|
||||||
v-for='groupAPI in API.favoriteFriendGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='moveFavorite(favorite.ref, groupAPI, "friend")'
|
|
||||||
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
|
||||||
el-button(type='text' size='mini' @click.stop style='margin-left: 5px')
|
|
||||||
el-checkbox(v-model='favorite.$selected')
|
|
||||||
template(v-else)
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.unfavorite_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
v-if='shiftHeld'
|
|
||||||
@click.stop='deleteFavorite(favorite.id)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-close'
|
|
||||||
circle
|
|
||||||
style='color: #f56c6c; margin-left: 5px')
|
|
||||||
el-button(
|
|
||||||
v-else
|
|
||||||
@click.stop='showFavoriteDialog("friend", favorite.id)'
|
|
||||||
type='default'
|
|
||||||
icon='el-icon-star-on'
|
|
||||||
size='mini'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
template(v-else)
|
|
||||||
.avatar
|
|
||||||
.detail
|
|
||||||
span(v-text='favorite.name || favorite.id')
|
|
||||||
el-button(
|
|
||||||
type='text'
|
|
||||||
icon='el-icon-close'
|
|
||||||
size='mini'
|
|
||||||
@click.stop='deleteFavorite(favorite.id)'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
div(
|
|
||||||
v-else
|
|
||||||
style='padding-top: 25px; width: 100%; display: flex; align-items: center; justify-content: center; color: rgb(144, 147, 153)')
|
|
||||||
span No Data
|
|
||||||
el-tab-pane(:label='$t("view.favorite.worlds.header")' lazy)
|
|
||||||
favorites-world-tab(
|
|
||||||
@show-world-export-dialog='showWorldExportDialog'
|
|
||||||
@show-world-import-dialog='showWorldImportDialog'
|
|
||||||
@save-sort-favorites-option='saveSortFavoritesOption'
|
|
||||||
@show-world-dialog='showWorldDialog'
|
|
||||||
@change-favorite-group-name='changeFavoriteGroupName'
|
|
||||||
@clear-favorite-group='clearFavoriteGroup'
|
|
||||||
@new-instance-self-invite='newInstanceSelfInvite'
|
|
||||||
@show-favorite-dialog='showFavoriteDialog'
|
|
||||||
@refresh-local-world-favorite='refreshLocalWorldFavorites'
|
|
||||||
@delete-local-world-favorite-group='deleteLocalWorldFavoriteGroup'
|
|
||||||
@search-world-favorites='searchWorldFavorites'
|
|
||||||
@remove-local-world-favorite='removeLocalWorldFavorite'
|
|
||||||
:sort-favorites.sync='sortFavorites'
|
|
||||||
:world-favorite-search-results='worldFavoriteSearchResults'
|
|
||||||
:hide-tooltips='hideTooltips'
|
|
||||||
:favorite-worlds='favoriteWorlds'
|
|
||||||
:edit-favorites-mode='editFavoritesMode'
|
|
||||||
:shift-held='shiftHeld'
|
|
||||||
:refresh-local-world-favorites='refreshLocalWorldFavorites'
|
|
||||||
:local-world-favorite-groups='localWorldFavoriteGroups'
|
|
||||||
:local-world-favorites='localWorldFavorites')
|
|
||||||
el-tab-pane(:label='$t("view.favorite.avatars.header")' lazy)
|
|
||||||
div(style='display: flex; align-items: center; justify-content: space-between')
|
|
||||||
div
|
|
||||||
el-button(size='small' @click='showAvatarExportDialog') {{ $t('view.favorite.export') }}
|
|
||||||
el-button(size='small' @click='showAvatarImportDialog' style='margin-left: 5px') {{ $t('view.favorite.import') }}
|
|
||||||
div(style='display: flex; align-items: center; font-size: 13px; margin-right: 10px')
|
|
||||||
span.name(style='margin-right: 5px; line-height: 10px') {{ $t('view.favorite.sort_by') }}
|
|
||||||
el-radio-group(
|
|
||||||
v-model='sortFavorites'
|
|
||||||
@change='saveSortFavoritesOption'
|
|
||||||
style='margin-right: 12px')
|
|
||||||
el-radio(:label='false') {{ $t('view.settings.appearance.appearance.sort_favorite_by_name') }}
|
|
||||||
el-radio(:label='true') {{ $t('view.settings.appearance.appearance.sort_favorite_by_date') }}
|
|
||||||
el-input(
|
|
||||||
v-model='avatarFavoriteSearch'
|
|
||||||
@input='searchAvatarFavorites'
|
|
||||||
clearable
|
|
||||||
size='mini'
|
|
||||||
:placeholder='$t("view.favorite.avatars.search")'
|
|
||||||
style='width: 200px')
|
|
||||||
.x-friend-list(style='margin-top: 10px')
|
|
||||||
div(
|
|
||||||
style='display: inline-block; width: 300px; margin-right: 15px'
|
|
||||||
v-for='favorite in avatarFavoriteSearchResults'
|
|
||||||
:key='favorite.id'
|
|
||||||
@click='showAvatarDialog(favorite.id)')
|
|
||||||
.x-friend-item
|
|
||||||
template(v-if='favorite.name')
|
|
||||||
.avatar
|
|
||||||
img(v-lazy='favorite.thumbnailImageUrl')
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.name')
|
|
||||||
span.extra(v-text='favorite.authorName')
|
|
||||||
template(v-else)
|
|
||||||
.avatar
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.id')
|
|
||||||
span(style='display: block; margin-top: 20px') {{ $t('view.favorite.avatars.vrchat_favorites') }}
|
|
||||||
el-collapse(style='border: 0')
|
|
||||||
el-collapse-item(v-for='group in API.favoriteAvatarGroups' :key='group.name')
|
|
||||||
template(slot='title')
|
|
||||||
span(
|
|
||||||
v-text='group.displayName'
|
|
||||||
style='font-weight: bold; font-size: 14px; margin-left: 10px')
|
|
||||||
span(style='color: #909399; font-size: 12px; margin-left: 10px') {{ group.count }}/{{ group.capacity }}
|
|
||||||
el-tooltip(
|
|
||||||
placement='top'
|
|
||||||
:content='$t("view.favorite.rename_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='changeFavoriteGroupName(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-edit'
|
|
||||||
circle
|
|
||||||
style='margin-left: 10px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.clear_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='clearFavoriteGroup(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-delete'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
.x-friend-list(v-if='group.count' style='margin-top: 10px')
|
|
||||||
div(
|
|
||||||
style='display: inline-block; width: 300px; margin-right: 15px'
|
|
||||||
v-for='favorite in groupedByGroupKeyFavoriteAvatars[group.key]'
|
|
||||||
:key='favorite.id'
|
|
||||||
@click='showAvatarDialog(favorite.id)')
|
|
||||||
.x-friend-item
|
|
||||||
template(v-if='favorite.ref')
|
|
||||||
.avatar
|
|
||||||
img(v-lazy='favorite.ref.thumbnailImageUrl')
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.ref.name')
|
|
||||||
span.extra(v-text='favorite.ref.authorName')
|
|
||||||
template(v-if='editFavoritesMode')
|
|
||||||
el-dropdown(
|
|
||||||
trigger='click'
|
|
||||||
@click.native.stop
|
|
||||||
size='mini'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='top'
|
|
||||||
:content='$t("view.favorite.move_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(type='default' icon='el-icon-back' size='mini' circle)
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
template(
|
|
||||||
v-if='groupAPI.name !== group.name'
|
|
||||||
v-for='groupAPI in API.favoriteAvatarGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='moveFavorite(favorite.ref, groupAPI, "avatar")'
|
|
||||||
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
|
||||||
el-button(type='text' size='mini' @click.stop style='margin-left: 5px')
|
|
||||||
el-checkbox(v-model='favorite.$selected')
|
|
||||||
template(v-else)
|
|
||||||
el-tooltip(
|
|
||||||
v-if='favorite.deleted'
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.unavailable_tooltip")')
|
|
||||||
i.el-icon-warning(style='color: #f56c6c; margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
v-if='favorite.ref.releaseStatus === "private"'
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.private")')
|
|
||||||
i.el-icon-warning(style='color: #e6a23c; margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
v-if='favorite.ref.releaseStatus !== "private" && !favorite.deleted'
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.select_avatar_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='selectAvatarWithConfirmation(favorite.id)'
|
|
||||||
:disabled='API.currentUser.currentAvatar === favorite.id'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-check'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.unfavorite_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
v-if='shiftHeld'
|
|
||||||
@click.stop='deleteFavorite(favorite.id)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-close'
|
|
||||||
circle
|
|
||||||
style='color: #f56c6c; margin-left: 5px')
|
|
||||||
el-button(
|
|
||||||
v-else
|
|
||||||
@click.stop='showFavoriteDialog("avatar", favorite.id)'
|
|
||||||
type='default'
|
|
||||||
icon='el-icon-star-on'
|
|
||||||
size='mini'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
template(v-else)
|
|
||||||
.avatar
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.name || favorite.id')
|
|
||||||
el-button(
|
|
||||||
type='text'
|
|
||||||
icon='el-icon-close'
|
|
||||||
size='mini'
|
|
||||||
@click.stop='deleteFavorite(favorite.id)'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
div(
|
|
||||||
v-else
|
|
||||||
style='padding-top: 25px; width: 100%; display: flex; align-items: center; justify-content: center; color: rgb(144, 147, 153)')
|
|
||||||
span No Data
|
|
||||||
el-collapse-item
|
|
||||||
template(slot='title')
|
|
||||||
span(style='font-weight: bold; font-size: 14px; margin-left: 10px') Local History
|
|
||||||
span(style='color: #909399; font-size: 12px; margin-left: 10px') {{ avatarHistoryArray.length }}/100
|
|
||||||
el-tooltip(placement='right' content='Clear' :disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='promptClearAvatarHistory'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-delete'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
.x-friend-list(v-if='avatarHistoryArray.length' style='margin-top: 10px')
|
|
||||||
div(
|
|
||||||
style='display: inline-block; width: 300px; margin-right: 15px'
|
|
||||||
v-for='favorite in avatarHistoryArray'
|
|
||||||
:key='favorite.id'
|
|
||||||
@click='showAvatarDialog(favorite.id)')
|
|
||||||
.x-friend-item
|
|
||||||
.avatar
|
|
||||||
img(v-lazy='favorite.thumbnailImageUrl')
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.name')
|
|
||||||
span.extra(v-text='favorite.authorName')
|
|
||||||
el-tooltip(
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.select_avatar_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='selectAvatarWithConfirmation(favorite.id)'
|
|
||||||
:disabled='API.currentUser.currentAvatar === favorite.id'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-check'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
template(v-if='API.cachedFavoritesByObjectId.has(favorite.id)')
|
|
||||||
el-tooltip(placement='right' content='Unfavorite' :disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='showFavoriteDialog("avatar", favorite.id)'
|
|
||||||
type='default'
|
|
||||||
icon='el-icon-star-on'
|
|
||||||
size='mini'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
template(v-else)
|
|
||||||
el-tooltip(placement='right' content='Favorite' :disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='showFavoriteDialog("avatar", favorite.id)'
|
|
||||||
type='default'
|
|
||||||
icon='el-icon-star-off'
|
|
||||||
size='mini'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
div(
|
|
||||||
v-else
|
|
||||||
style='padding-top: 25px; width: 100%; display: flex; align-items: center; justify-content: center; color: rgb(144, 147, 153)')
|
|
||||||
span No Data
|
|
||||||
span(style='display: block; margin-top: 20px') {{ $t('view.favorite.avatars.local_favorites') }}
|
|
||||||
br
|
|
||||||
el-button(
|
|
||||||
size='small'
|
|
||||||
:disabled='!isLocalUserVrcplusSupporter()'
|
|
||||||
@click='promptNewLocalAvatarFavoriteGroup') {{ $t('view.favorite.avatars.new_group') }}
|
|
||||||
el-button(
|
|
||||||
v-if='!refreshingLocalFavorites'
|
|
||||||
size='small'
|
|
||||||
@click='refreshLocalAvatarFavorites'
|
|
||||||
style='margin-left: 5px') {{ $t('view.favorite.avatars.refresh') }}
|
|
||||||
el-button(v-else size='small' @click='refreshingLocalFavorites = false' style='margin-left: 5px')
|
|
||||||
i.el-icon-loading(style='margin-right: 5px')
|
|
||||||
span {{ $t('view.favorite.avatars.cancel_refresh') }}
|
|
||||||
el-collapse-item(
|
|
||||||
v-for='group in localAvatarFavoriteGroups'
|
|
||||||
v-if='localAvatarFavorites[group]'
|
|
||||||
:key='group')
|
|
||||||
template(slot='title')
|
|
||||||
span(v-text='group' style='font-weight: bold; font-size: 14px; margin-left: 10px')
|
|
||||||
span(style='color: #909399; font-size: 12px; margin-left: 10px') {{ getLocalAvatarFavoriteGroupLength(group) }}
|
|
||||||
el-tooltip(
|
|
||||||
placement='top'
|
|
||||||
:content='$t("view.favorite.rename_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='promptLocalAvatarFavoriteGroupRename(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-edit'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.delete_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='promptLocalAvatarFavoriteGroupDelete(group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-delete'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
.x-friend-list(style='margin-top: 10px' v-if='localAvatarFavorites[group].length')
|
|
||||||
div(
|
|
||||||
style='display: inline-block; width: 300px; margin-right: 15px'
|
|
||||||
v-for='favorite in localAvatarFavorites[group]'
|
|
||||||
:key='favorite.id'
|
|
||||||
@click='showAvatarDialog(favorite.id)')
|
|
||||||
.x-friend-item
|
|
||||||
template(v-if='favorite.name')
|
|
||||||
.avatar
|
|
||||||
img(v-lazy='favorite.thumbnailImageUrl')
|
|
||||||
.detail
|
|
||||||
span.name(v-text='favorite.name')
|
|
||||||
span.extra(v-text='favorite.authorName')
|
|
||||||
template(v-if='editFavoritesMode')
|
|
||||||
el-dropdown(
|
|
||||||
trigger='click'
|
|
||||||
@click.native.stop
|
|
||||||
size='mini'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.copy_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(type='default' icon='el-icon-back' size='mini' circle)
|
|
||||||
el-dropdown-menu(#default='dropdown')
|
|
||||||
template(v-for='groupAPI in API.favoriteAvatarGroups')
|
|
||||||
el-dropdown-item(
|
|
||||||
:key='groupAPI.name'
|
|
||||||
style='display: block; margin: 10px 0'
|
|
||||||
@click.native='addFavoriteAvatar(favorite, groupAPI, true)'
|
|
||||||
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
|
|
||||||
template(v-else)
|
|
||||||
el-tooltip(
|
|
||||||
placement='left'
|
|
||||||
:content='$t("view.favorite.select_avatar_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
@click.stop='selectAvatarWithConfirmation(favorite.id)'
|
|
||||||
:disabled='API.currentUser.currentAvatar === favorite.id'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-check'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
el-tooltip(
|
|
||||||
placement='right'
|
|
||||||
:content='$t("view.favorite.unfavorite_tooltip")'
|
|
||||||
:disabled='hideTooltips')
|
|
||||||
el-button(
|
|
||||||
v-if='shiftHeld'
|
|
||||||
@click.stop='removeLocalAvatarFavorite(favorite.id, group)'
|
|
||||||
size='mini'
|
|
||||||
icon='el-icon-close'
|
|
||||||
circle
|
|
||||||
style='color: #f56c6c; margin-left: 5px')
|
|
||||||
el-button(
|
|
||||||
v-else
|
|
||||||
@click.stop='showFavoriteDialog("avatar", favorite.id)'
|
|
||||||
type='default'
|
|
||||||
icon='el-icon-star-on'
|
|
||||||
size='mini'
|
|
||||||
circle
|
|
||||||
style='margin-left: 5px')
|
|
||||||
template(v-else)
|
|
||||||
.avatar
|
|
||||||
.detail
|
|
||||||
span(v-text='favorite.id')
|
|
||||||
el-button(
|
|
||||||
type='text'
|
|
||||||
icon='el-icon-close'
|
|
||||||
size='mini'
|
|
||||||
@click.stop='removeLocalAvatarFavorite(favorite.id, group)'
|
|
||||||
style='margin-left: 5px')
|
|
||||||
div(
|
|
||||||
v-else
|
|
||||||
style='padding-top: 25px; width: 100%; display: flex; align-items: center; justify-content: center; color: rgb(144, 147, 153)')
|
|
||||||
span No Data
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="aside" class="x-aside-container">
|
<div id="aside" class="x-aside-container" v-show="isSideBarTabShow">
|
||||||
<div style="display: flex; align-items: baseline">
|
<div style="display: flex; align-items: baseline">
|
||||||
<el-select
|
<el-select
|
||||||
value=""
|
value=""
|
||||||
@@ -125,6 +125,8 @@
|
|||||||
hideNicknames: Boolean,
|
hideNicknames: Boolean,
|
||||||
isHideFriendsInSameInstance: Boolean,
|
isHideFriendsInSameInstance: Boolean,
|
||||||
|
|
||||||
|
isSideBarTabShow: Boolean,
|
||||||
|
|
||||||
quickSearchRemoteMethod: Function,
|
quickSearchRemoteMethod: Function,
|
||||||
quickSearchItems: Array,
|
quickSearchItems: Array,
|
||||||
onlineFriendCount: Number,
|
onlineFriendCount: Number,
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :visible.sync="isDialogVisible" :title="$t('dialog.avatar_export.header')" width="650px">
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="exportSelectedOptions"
|
||||||
|
style="margin-bottom: 10px"
|
||||||
|
@change="updateAvatarExportDialog()">
|
||||||
|
<template v-for="option in exportSelectOptions">
|
||||||
|
<el-checkbox :key="option.value" :label="option.label"></el-checkbox>
|
||||||
|
</template>
|
||||||
|
</el-checkbox-group>
|
||||||
|
|
||||||
|
<el-dropdown trigger="click" size="small" @click.native.stop>
|
||||||
|
<el-button size="mini">
|
||||||
|
<span v-if="avatarExportFavoriteGroup">
|
||||||
|
{{ avatarExportFavoriteGroup.displayName }} ({{ avatarExportFavoriteGroup.count }}/{{
|
||||||
|
avatarExportFavoriteGroup.capacity
|
||||||
|
}})
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
All Favorites
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item style="display: block; margin: 10px 0" @click.native="selectAvatarExportGroup(null)">
|
||||||
|
All Favorites
|
||||||
|
</el-dropdown-item>
|
||||||
|
<template v-for="groupAPI in API.favoriteAvatarGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="groupAPI.name"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectAvatarExportGroup(groupAPI)">
|
||||||
|
{{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
|
||||||
|
<el-dropdown trigger="click" size="small" style="margin-left: 10px" @click.native.stop>
|
||||||
|
<el-button size="mini">
|
||||||
|
<span v-if="avatarExportLocalFavoriteGroup">
|
||||||
|
{{ avatarExportLocalFavoriteGroup }} ({{
|
||||||
|
getLocalAvatarFavoriteGroupLength(avatarExportLocalFavoriteGroup)
|
||||||
|
}})
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
Select Group
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectAvatarExportLocalGroup(null)">
|
||||||
|
None
|
||||||
|
</el-dropdown-item>
|
||||||
|
<template v-for="group in localAvatarFavoriteGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="group"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectAvatarExportLocalGroup(group)">
|
||||||
|
{{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<br />
|
||||||
|
<el-input
|
||||||
|
v-model="avatarExportContent"
|
||||||
|
type="textarea"
|
||||||
|
size="mini"
|
||||||
|
rows="15"
|
||||||
|
resize="none"
|
||||||
|
readonly
|
||||||
|
style="margin-top: 15px"
|
||||||
|
@click.native="handleCopyAvatarExportData"></el-input>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AvatarExportDialog',
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
avatarExportDialogVisible: Boolean,
|
||||||
|
favoriteAvatars: Array,
|
||||||
|
localAvatarFavoriteGroups: Array,
|
||||||
|
localAvatarFavorites: Object,
|
||||||
|
localAvatarFavoritesList: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
avatarExportContent: '',
|
||||||
|
avatarExportFavoriteGroup: null,
|
||||||
|
avatarExportLocalFavoriteGroup: null,
|
||||||
|
exportSelectedOptions: ['ID', 'Name'],
|
||||||
|
exportSelectOptions: [
|
||||||
|
{ label: 'ID', value: 'id' },
|
||||||
|
{ label: 'Name', value: 'name' },
|
||||||
|
{ label: 'Author ID', value: 'authorId' },
|
||||||
|
{ label: 'Author Name', value: 'authorName' },
|
||||||
|
{ label: 'Thumbnail', value: 'thumbnailImageUrl' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.avatarExportDialogVisible;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:avatar-export-dialog-visible', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
avatarExportDialogVisible(visible) {
|
||||||
|
if (visible) {
|
||||||
|
this.showAvatarExportDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showAvatarExportDialog() {
|
||||||
|
this.avatarExportFavoriteGroup = null;
|
||||||
|
this.avatarExportLocalFavoriteGroup = null;
|
||||||
|
this.updateAvatarExportDialog();
|
||||||
|
},
|
||||||
|
handleCopyAvatarExportData(event) {
|
||||||
|
if (event.target.tagName === 'TEXTAREA') {
|
||||||
|
event.target.select();
|
||||||
|
}
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(this.avatarExportContent)
|
||||||
|
.then(() => {
|
||||||
|
this.$message({
|
||||||
|
message: 'Copied successfully!',
|
||||||
|
type: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Copy failed:', err);
|
||||||
|
this.$message.error('Copy failed!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateAvatarExportDialog() {
|
||||||
|
const formatter = function (str) {
|
||||||
|
if (/[\x00-\x1f,"]/.test(str) === true) {
|
||||||
|
return `"${str.replace(/"/g, '""')}"`;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
const propsForQuery = this.exportSelectOptions
|
||||||
|
.filter((option) => this.exportSelectedOptions.includes(option.label))
|
||||||
|
.map((option) => option.value);
|
||||||
|
|
||||||
|
function resText(ref) {
|
||||||
|
let resArr = [];
|
||||||
|
propsForQuery.forEach((e) => {
|
||||||
|
resArr.push(formatter(ref?.[e]));
|
||||||
|
});
|
||||||
|
return resArr.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = [this.exportSelectedOptions.join(',')];
|
||||||
|
|
||||||
|
if (this.avatarExportFavoriteGroup) {
|
||||||
|
this.API.favoriteAvatarGroups.forEach((group) => {
|
||||||
|
if (!this.avatarExportFavoriteGroup || this.avatarExportFavoriteGroup === group) {
|
||||||
|
this.favoriteAvatars.forEach((ref) => {
|
||||||
|
if (group.key === ref.groupKey) {
|
||||||
|
lines.push(resText(ref.ref));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (this.avatarExportLocalFavoriteGroup) {
|
||||||
|
const favoriteGroup = this.localAvatarFavorites[this.avatarExportLocalFavoriteGroup];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < favoriteGroup.length; ++i) {
|
||||||
|
const ref = favoriteGroup[i];
|
||||||
|
lines.push(resText(ref));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// export all
|
||||||
|
this.favoriteAvatars.forEach((ref) => {
|
||||||
|
lines.push(resText(ref.ref));
|
||||||
|
});
|
||||||
|
for (let i = 0; i < this.localAvatarFavoritesList.length; ++i) {
|
||||||
|
const avatarId = this.localAvatarFavoritesList[i];
|
||||||
|
const ref = this.API.cachedAvatars.get(avatarId);
|
||||||
|
if (typeof ref !== 'undefined') {
|
||||||
|
lines.push(resText(ref));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.avatarExportContent = lines.join('\n');
|
||||||
|
},
|
||||||
|
selectAvatarExportGroup(group) {
|
||||||
|
this.avatarExportFavoriteGroup = group;
|
||||||
|
this.avatarExportLocalFavoriteGroup = null;
|
||||||
|
this.updateAvatarExportDialog();
|
||||||
|
},
|
||||||
|
selectAvatarExportLocalGroup(group) {
|
||||||
|
this.avatarExportLocalFavoriteGroup = group;
|
||||||
|
this.avatarExportFavoriteGroup = null;
|
||||||
|
this.updateAvatarExportDialog();
|
||||||
|
},
|
||||||
|
getLocalAvatarFavoriteGroupLength(group) {
|
||||||
|
const favoriteGroup = this.localAvatarFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return favoriteGroup.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="isDialogVisible"
|
||||||
|
class="x-dialog"
|
||||||
|
:title="$t('dialog.friend_export.header')"
|
||||||
|
width="650px"
|
||||||
|
destroy-on-close>
|
||||||
|
<el-dropdown trigger="click" size="small" @click.native.stop>
|
||||||
|
<el-button size="mini">
|
||||||
|
<span v-if="friendExportFavoriteGroup">
|
||||||
|
{{ friendExportFavoriteGroup.displayName }} ({{ friendExportFavoriteGroup.count }}/{{
|
||||||
|
friendExportFavoriteGroup.capacity
|
||||||
|
}})
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<span v-else>All Favorites <i class="el-icon-arrow-down el-icon--right"></i></span>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item style="display: block; margin: 10px 0" @click.native="selectFriendExportGroup(null)">
|
||||||
|
All Favorites
|
||||||
|
</el-dropdown-item>
|
||||||
|
<template v-for="groupAPI in API.favoriteFriendGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="groupAPI.name"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectFriendExportGroup(groupAPI)">
|
||||||
|
{{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
<br />
|
||||||
|
<el-input
|
||||||
|
v-model="friendExportContent"
|
||||||
|
type="textarea"
|
||||||
|
size="mini"
|
||||||
|
rows="15"
|
||||||
|
resize="none"
|
||||||
|
readonly
|
||||||
|
style="margin-top: 15px"
|
||||||
|
@click.native="handleCopyFriendExportData"></el-input>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FriendExportDialog',
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
friendExportDialogVisible: Boolean,
|
||||||
|
favoriteFriends: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
friendExportFavoriteGroup: null,
|
||||||
|
friendExportContent: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.friendExportDialogVisible;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:friend-export-dialog-visible', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
friendExportDialogVisible(value) {
|
||||||
|
if (value) {
|
||||||
|
this.showFriendExportDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showFriendExportDialog() {
|
||||||
|
this.friendExportFavoriteGroup = null;
|
||||||
|
this.updateFriendExportDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCopyFriendExportData(event) {
|
||||||
|
if (event.target.tagName === 'TEXTAREA') {
|
||||||
|
event.target.select();
|
||||||
|
}
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(this.friendExportContent)
|
||||||
|
.then(() => {
|
||||||
|
this.$message({
|
||||||
|
message: 'Copied successfully!',
|
||||||
|
type: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Copy failed:', err);
|
||||||
|
this.$message.error('Copy failed!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateFriendExportDialog() {
|
||||||
|
const _ = function (str) {
|
||||||
|
if (/[\x00-\x1f,"]/.test(str) === true) {
|
||||||
|
return `"${str.replace(/"/g, '""')}"`;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
const lines = ['UserID,Name'];
|
||||||
|
this.API.favoriteFriendGroups.forEach((group) => {
|
||||||
|
if (!this.friendExportFavoriteGroup || this.friendExportFavoriteGroup === group) {
|
||||||
|
this.favoriteFriends.forEach((ref) => {
|
||||||
|
if (group.key === ref.groupKey) {
|
||||||
|
lines.push(`${_(ref.id)},${_(ref.name)}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.friendExportContent = lines.join('\n');
|
||||||
|
},
|
||||||
|
|
||||||
|
selectFriendExportGroup(group) {
|
||||||
|
this.friendExportFavoriteGroup = group;
|
||||||
|
this.updateFriendExportDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -862,7 +862,7 @@
|
|||||||
memo
|
memo
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
database.deleteWorldMemo(id);
|
database.deleteWorldMemo(worldId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showPreviousInstancesWorldDialog(world) {
|
showPreviousInstancesWorldDialog(world) {
|
||||||
|
|||||||
@@ -0,0 +1,231 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :visible.sync="isDialogVisible" :title="$t('dialog.world_export.header')" width="650px">
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="exportSelectedOptions"
|
||||||
|
style="margin-bottom: 10px"
|
||||||
|
@change="updateWorldExportDialog">
|
||||||
|
<template v-for="option in exportSelectOptions">
|
||||||
|
<el-checkbox :key="option.value" :label="option.label"></el-checkbox>
|
||||||
|
</template>
|
||||||
|
</el-checkbox-group>
|
||||||
|
|
||||||
|
<el-dropdown trigger="click" size="small" @click.native.stop>
|
||||||
|
<el-button size="mini">
|
||||||
|
<span v-if="worldExportFavoriteGroup">
|
||||||
|
{{ worldExportFavoriteGroup.displayName }} ({{ worldExportFavoriteGroup.count }}/{{
|
||||||
|
worldExportFavoriteGroup.capacity
|
||||||
|
}})
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
All Favorites
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item style="display: block; margin: 10px 0" @click.native="selectWorldExportGroup(null)">
|
||||||
|
None
|
||||||
|
</el-dropdown-item>
|
||||||
|
<template v-for="groupAPI in API.favoriteWorldGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="groupAPI.name"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectWorldExportGroup(groupAPI)">
|
||||||
|
{{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
|
||||||
|
<el-dropdown trigger="click" size="small" style="margin-left: 10px" @click.native.stop>
|
||||||
|
<el-button size="mini">
|
||||||
|
<span v-if="worldExportLocalFavoriteGroup">
|
||||||
|
{{ worldExportLocalFavoriteGroup }} ({{
|
||||||
|
getLocalWorldFavoriteGroupLength(worldExportLocalFavoriteGroup)
|
||||||
|
}})
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
Select Group
|
||||||
|
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||||
|
</span>
|
||||||
|
</el-button>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectWorldExportLocalGroup(null)">
|
||||||
|
None
|
||||||
|
</el-dropdown-item>
|
||||||
|
<template v-for="group in localWorldFavoriteGroups">
|
||||||
|
<el-dropdown-item
|
||||||
|
:key="group"
|
||||||
|
style="display: block; margin: 10px 0"
|
||||||
|
@click.native="selectWorldExportLocalGroup(group)">
|
||||||
|
{{ group }} ({{ localWorldFavorites[group].length }})
|
||||||
|
</el-dropdown-item>
|
||||||
|
</template>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<el-input
|
||||||
|
v-model="worldExportContent"
|
||||||
|
type="textarea"
|
||||||
|
size="mini"
|
||||||
|
rows="15"
|
||||||
|
resize="none"
|
||||||
|
readonly
|
||||||
|
style="margin-top: 15px"
|
||||||
|
@click.native="handleCopyWorldExportData"></el-input>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'WorldExportDialog',
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
favoriteWorlds: Array,
|
||||||
|
worldExportDialogVisible: Boolean,
|
||||||
|
localWorldFavorites: Object,
|
||||||
|
localWorldFavoriteGroups: Array,
|
||||||
|
localWorldFavoritesList: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
worldExportContent: '',
|
||||||
|
worldExportFavoriteGroup: null,
|
||||||
|
worldExportLocalFavoriteGroup: null,
|
||||||
|
// Storage of selected filtering options for model and world export
|
||||||
|
exportSelectedOptions: ['ID', 'Name'],
|
||||||
|
exportSelectOptions: [
|
||||||
|
{ label: 'ID', value: 'id' },
|
||||||
|
{ label: 'Name', value: 'name' },
|
||||||
|
{ label: 'Author ID', value: 'authorId' },
|
||||||
|
{ label: 'Author Name', value: 'authorName' },
|
||||||
|
{ label: 'Thumbnail', value: 'thumbnailImageUrl' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDialogVisible: {
|
||||||
|
get() {
|
||||||
|
return this.worldExportDialogVisible;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:world-export-dialog-visible', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
worldExportDialogVisible(value) {
|
||||||
|
if (value) {
|
||||||
|
this.showWorldExportDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showWorldExportDialog() {
|
||||||
|
this.worldExportFavoriteGroup = null;
|
||||||
|
this.worldExportLocalFavoriteGroup = null;
|
||||||
|
this.updateWorldExportDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCopyWorldExportData(event) {
|
||||||
|
if (event.target.tagName === 'TEXTAREA') {
|
||||||
|
event.target.select();
|
||||||
|
}
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(this.worldExportContent)
|
||||||
|
.then(() => {
|
||||||
|
this.$message({
|
||||||
|
message: 'Copied successfully!',
|
||||||
|
type: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Copy failed:', err);
|
||||||
|
this.$message.error('Copy failed!');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWorldExportDialog() {
|
||||||
|
const formatter = function (str) {
|
||||||
|
if (/[\x00-\x1f,"]/.test(str) === true) {
|
||||||
|
return `"${str.replace(/"/g, '""')}"`;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
const propsForQuery = this.exportSelectOptions
|
||||||
|
.filter((option) => this.exportSelectedOptions.includes(option.label))
|
||||||
|
.map((option) => option.value);
|
||||||
|
|
||||||
|
function resText(ref) {
|
||||||
|
let resArr = [];
|
||||||
|
propsForQuery.forEach((e) => {
|
||||||
|
resArr.push(formatter(ref?.[e]));
|
||||||
|
});
|
||||||
|
return resArr.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = [this.exportSelectedOptions.join(',')];
|
||||||
|
|
||||||
|
if (this.worldExportFavoriteGroup) {
|
||||||
|
this.API.favoriteWorldGroups.forEach((group) => {
|
||||||
|
if (this.worldExportFavoriteGroup === group) {
|
||||||
|
this.favoriteWorlds.forEach((ref) => {
|
||||||
|
if (group.key === ref.groupKey) {
|
||||||
|
lines.push(resText(ref.ref));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (this.worldExportLocalFavoriteGroup) {
|
||||||
|
const favoriteGroup = this.localWorldFavorites[this.worldExportLocalFavoriteGroup];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < favoriteGroup.length; ++i) {
|
||||||
|
const ref = favoriteGroup[i];
|
||||||
|
lines.push(resText(ref));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// export all
|
||||||
|
this.favoriteWorlds.forEach((ref) => {
|
||||||
|
lines.push(resText(ref.ref));
|
||||||
|
});
|
||||||
|
for (let i = 0; i < this.localWorldFavoritesList.length; ++i) {
|
||||||
|
const worldId = this.localWorldFavoritesList[i];
|
||||||
|
const ref = this.API.cachedWorlds.get(worldId);
|
||||||
|
if (typeof ref !== 'undefined') {
|
||||||
|
lines.push(resText(ref));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.worldExportContent = lines.join('\n');
|
||||||
|
},
|
||||||
|
|
||||||
|
selectWorldExportGroup(group) {
|
||||||
|
this.worldExportFavoriteGroup = group;
|
||||||
|
this.worldExportLocalFavoriteGroup = null;
|
||||||
|
this.updateWorldExportDialog();
|
||||||
|
},
|
||||||
|
|
||||||
|
selectWorldExportLocalGroup(group) {
|
||||||
|
this.worldExportLocalFavoriteGroup = group;
|
||||||
|
this.worldExportFavoriteGroup = null;
|
||||||
|
this.updateWorldExportDialog();
|
||||||
|
},
|
||||||
|
getLocalWorldFavoriteGroupLength(group) {
|
||||||
|
const favoriteGroup = this.localWorldFavorites[group];
|
||||||
|
if (!favoriteGroup) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return favoriteGroup.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
<template>
|
||||||
|
<div v-show="menuActiveIndex === 'favorite'" class="x-container">
|
||||||
|
<div style="font-size: 13px; position: absolute; display: flex; right: 0; z-index: 1; margin-right: 15px">
|
||||||
|
<div v-if="editFavoritesMode" style="display: inline-block; margin-right: 10px">
|
||||||
|
<el-button size="small" @click="clearBulkFavoriteSelection">{{ $t('view.favorite.clear') }}</el-button>
|
||||||
|
<el-button size="small" @click="bulkCopyFavoriteSelection">{{ $t('view.favorite.copy') }}</el-button>
|
||||||
|
<el-button size="small" @click="showBulkUnfavoriteSelectionConfirm">{{
|
||||||
|
$t('view.favorite.bulk_unfavorite')
|
||||||
|
}}</el-button>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex; align-items: center; margin-right: 10px">
|
||||||
|
<span class="name">{{ $t('view.favorite.edit_mode') }}</span>
|
||||||
|
<el-switch v-model="editFavoritesMode" style="margin-left: 5px"></el-switch>
|
||||||
|
</div>
|
||||||
|
<el-tooltip placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips">
|
||||||
|
<el-button
|
||||||
|
type="default"
|
||||||
|
:loading="API.isFavoriteLoading"
|
||||||
|
@click="
|
||||||
|
API.refreshFavorites();
|
||||||
|
getLocalWorldFavorites();
|
||||||
|
"
|
||||||
|
size="small"
|
||||||
|
icon="el-icon-refresh"
|
||||||
|
circle></el-button>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
<el-tabs type="card" v-loading="API.isFavoriteLoading" style="height: 100%">
|
||||||
|
<el-tab-pane :label="$t('view.favorite.friends.header')" lazy>
|
||||||
|
<favorites-friend-tab
|
||||||
|
:favorite-friends="favoriteFriends"
|
||||||
|
:sort-favorites.sync="isSortByTime"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
:grouped-by-group-key-favorite-friends="groupedByGroupKeyFavoriteFriends"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
@show-friend-import-dialog="showFriendImportDialog"
|
||||||
|
@save-sort-favorites-option="saveSortFavoritesOption"
|
||||||
|
@change-favorite-group-name="changeFavoriteGroupName" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('view.favorite.worlds.header')" lazy>
|
||||||
|
<favorites-world-tab
|
||||||
|
@show-world-import-dialog="showWorldImportDialog"
|
||||||
|
@save-sort-favorites-option="saveSortFavoritesOption"
|
||||||
|
@show-world-dialog="showWorldDialog"
|
||||||
|
@change-favorite-group-name="changeFavoriteGroupName"
|
||||||
|
@new-instance-self-invite="newInstanceSelfInvite"
|
||||||
|
@show-favorite-dialog="showFavoriteDialog"
|
||||||
|
@refresh-local-world-favorite="refreshLocalWorldFavorites"
|
||||||
|
@delete-local-world-favorite-group="deleteLocalWorldFavoriteGroup"
|
||||||
|
@remove-local-world-favorite="removeLocalWorldFavorite"
|
||||||
|
@rename-local-world-favorite-group="renameLocalWorldFavoriteGroup"
|
||||||
|
@new-local-world-favorite-group="newLocalWorldFavoriteGroup"
|
||||||
|
:sort-favorites.sync="isSortByTime"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
:favorite-worlds="favoriteWorlds"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
:shift-held="shiftHeld"
|
||||||
|
:refresh-local-world-favorites="refreshLocalWorldFavorites"
|
||||||
|
:local-world-favorite-groups="localWorldFavoriteGroups"
|
||||||
|
:local-world-favorites="localWorldFavorites"
|
||||||
|
:local-world-favorites-list="localWorldFavoritesList" />
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('view.favorite.avatars.header')" lazy>
|
||||||
|
<favorites-avatar-tab
|
||||||
|
:sort-favorites.sync="isSortByTime"
|
||||||
|
:hide-tooltips="hideTooltips"
|
||||||
|
:shift-held="shiftHeld"
|
||||||
|
:edit-favorites-mode="editFavoritesMode"
|
||||||
|
:avatar-history-array="avatarHistoryArray"
|
||||||
|
:refreshing-local-favorites="refreshingLocalFavorites"
|
||||||
|
:local-avatar-favorite-groups="localAvatarFavoriteGroups"
|
||||||
|
:local-avatar-favorites="localAvatarFavorites"
|
||||||
|
:favorite-avatars="favoriteAvatars"
|
||||||
|
:local-avatar-favorites-list="localAvatarFavoritesList"
|
||||||
|
@show-avatar-import-dialog="showAvatarImportDialog"
|
||||||
|
@save-sort-favorites-option="saveSortFavoritesOption"
|
||||||
|
@show-avatar-dialog="showAvatarDialog"
|
||||||
|
@show-favorite-dialog="showFavoriteDialog"
|
||||||
|
@change-favorite-group-name="changeFavoriteGroupName"
|
||||||
|
@remove-local-avatar-favorite="removeLocalAvatarFavorite"
|
||||||
|
@select-avatar-with-confirmation="selectAvatarWithConfirmation"
|
||||||
|
@prompt-clear-avatar-history="promptClearAvatarHistory"
|
||||||
|
@prompt-new-local-avatar-favorite-group="promptNewLocalAvatarFavoriteGroup"
|
||||||
|
@refresh-local-avatar-favorites="refreshLocalAvatarFavorites"
|
||||||
|
@prompt-local-avatar-favorite-group-rename="promptLocalAvatarFavoriteGroupRename"
|
||||||
|
@prompt-local-avatar-favorite-group-delete="promptLocalAvatarFavoriteGroupDelete" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FavoritesFriendTab from '../../components/favorites/FavoritesFriendTab.vue';
|
||||||
|
import FavoritesWorldTab from '../../components/favorites/FavoritesWorldTab.vue';
|
||||||
|
import FavoritesAvatarTab from '../../components/favorites/FavoritesAvatarTab.vue';
|
||||||
|
import { avatarRequest, favoriteRequest, worldRequest } from '../../classes/request';
|
||||||
|
import * as workerTimers from 'worker-timers';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FavoritesTab',
|
||||||
|
components: {
|
||||||
|
FavoritesFriendTab,
|
||||||
|
FavoritesWorldTab,
|
||||||
|
FavoritesAvatarTab
|
||||||
|
},
|
||||||
|
inject: ['API'],
|
||||||
|
props: {
|
||||||
|
menuActiveIndex: String,
|
||||||
|
hideTooltips: Boolean,
|
||||||
|
shiftHeld: Boolean,
|
||||||
|
favoriteFriends: Array,
|
||||||
|
sortFavorites: Boolean,
|
||||||
|
groupedByGroupKeyFavoriteFriends: Object,
|
||||||
|
favoriteWorlds: Array,
|
||||||
|
localWorldFavoriteGroups: Array,
|
||||||
|
localWorldFavorites: Object,
|
||||||
|
avatarHistoryArray: Array,
|
||||||
|
localAvatarFavoriteGroups: Array,
|
||||||
|
localAvatarFavorites: Object,
|
||||||
|
favoriteAvatars: Array,
|
||||||
|
localAvatarFavoritesList: Array,
|
||||||
|
localWorldFavoritesList: Array
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editFavoritesMode: false,
|
||||||
|
refreshingLocalFavorites: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isSortByTime: {
|
||||||
|
get() {
|
||||||
|
return this.sortFavorites;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:sort-favorites', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showBulkUnfavoriteSelectionConfirm() {
|
||||||
|
const elementsTicked = [];
|
||||||
|
// check favorites type
|
||||||
|
for (const ctx of this.favoriteFriends) {
|
||||||
|
if (ctx.$selected) {
|
||||||
|
elementsTicked.push(ctx.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const ctx of this.favoriteWorlds) {
|
||||||
|
if (ctx.$selected) {
|
||||||
|
elementsTicked.push(ctx.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const ctx of this.favoriteAvatars) {
|
||||||
|
if (ctx.$selected) {
|
||||||
|
elementsTicked.push(ctx.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elementsTicked.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$confirm(
|
||||||
|
`Are you sure you want to unfavorite ${elementsTicked.length} favorites?
|
||||||
|
This action cannot be undone.`,
|
||||||
|
`Delete ${elementsTicked.length} favorites?`,
|
||||||
|
{
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
type: 'info',
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
this.bulkUnfavoriteSelection(elementsTicked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
bulkUnfavoriteSelection(elementsTicked) {
|
||||||
|
for (const id of elementsTicked) {
|
||||||
|
favoriteRequest.deleteFavorite({
|
||||||
|
objectId: id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.editFavoritesMode = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
changeFavoriteGroupName(ctx) {
|
||||||
|
this.$prompt(
|
||||||
|
$t('prompt.change_favorite_group_name.description'),
|
||||||
|
$t('prompt.change_favorite_group_name.header'),
|
||||||
|
{
|
||||||
|
distinguishCancelAndClose: true,
|
||||||
|
cancelButtonText: $t('prompt.change_favorite_group_name.cancel'),
|
||||||
|
confirmButtonText: $t('prompt.change_favorite_group_name.change'),
|
||||||
|
inputPlaceholder: $t('prompt.change_favorite_group_name.input_placeholder'),
|
||||||
|
inputValue: ctx.displayName,
|
||||||
|
inputPattern: /\S+/,
|
||||||
|
inputErrorMessage: $t('prompt.change_favorite_group_name.input_error'),
|
||||||
|
callback: (action, instance) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
favoriteRequest
|
||||||
|
.saveFavoriteGroup({
|
||||||
|
type: ctx.type,
|
||||||
|
group: ctx.name,
|
||||||
|
displayName: instance.inputValue
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$message({
|
||||||
|
message: $t('prompt.change_favorite_group_name.message.success'),
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
// load new group name
|
||||||
|
this.API.refreshFavoriteGroups();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async refreshLocalAvatarFavorites() {
|
||||||
|
if (this.refreshingLocalFavorites) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.refreshingLocalFavorites = true;
|
||||||
|
for (const avatarId of this.localAvatarFavoritesList) {
|
||||||
|
if (!this.refreshingLocalFavorites) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await avatarRequest.getAvatar({
|
||||||
|
avatarId
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
workerTimers.setTimeout(resolve, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.refreshingLocalFavorites = false;
|
||||||
|
},
|
||||||
|
async refreshLocalWorldFavorites() {
|
||||||
|
if (this.refreshingLocalFavorites) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.refreshingLocalFavorites = true;
|
||||||
|
for (const worldId of this.localWorldFavoritesList) {
|
||||||
|
if (!this.refreshingLocalFavorites) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await worldRequest.getWorld({
|
||||||
|
worldId
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
workerTimers.setTimeout(resolve, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.refreshingLocalFavorites = false;
|
||||||
|
},
|
||||||
|
clearBulkFavoriteSelection() {
|
||||||
|
this.$emit('clear-bulk-favorite-selection');
|
||||||
|
},
|
||||||
|
bulkCopyFavoriteSelection() {
|
||||||
|
this.$emit('bulk-copy-favorite-selection');
|
||||||
|
},
|
||||||
|
getLocalWorldFavorites() {
|
||||||
|
this.$emit('get-local-world-favorites');
|
||||||
|
},
|
||||||
|
showFriendImportDialog() {
|
||||||
|
this.$emit('show-friend-import-dialog');
|
||||||
|
},
|
||||||
|
saveSortFavoritesOption() {
|
||||||
|
this.$emit('save-sort-favorites-option');
|
||||||
|
},
|
||||||
|
showWorldImportDialog() {
|
||||||
|
this.$emit('show-world-import-dialog');
|
||||||
|
},
|
||||||
|
showWorldDialog(tag, shortName) {
|
||||||
|
this.$emit('show-world-dialog', tag, shortName);
|
||||||
|
},
|
||||||
|
newInstanceSelfInvite(worldId) {
|
||||||
|
this.$emit('new-instance-self-invite', worldId);
|
||||||
|
},
|
||||||
|
showFavoriteDialog(type, objectId) {
|
||||||
|
this.$emit('show-favorite-dialog', type, objectId);
|
||||||
|
},
|
||||||
|
deleteLocalWorldFavoriteGroup(group) {
|
||||||
|
this.$emit('delete-local-world-favorite-group', group);
|
||||||
|
},
|
||||||
|
removeLocalWorldFavorite(worldId, group) {
|
||||||
|
this.$emit('remove-local-world-favorite', worldId, group);
|
||||||
|
},
|
||||||
|
showAvatarImportDialog() {
|
||||||
|
this.$emit('show-avatar-import-dialog');
|
||||||
|
},
|
||||||
|
showAvatarDialog(avatarId) {
|
||||||
|
this.$emit('show-avatar-dialog', avatarId);
|
||||||
|
},
|
||||||
|
removeLocalAvatarFavorite(avatarId, group) {
|
||||||
|
this.$emit('remove-local-avatar-favorite', avatarId, group);
|
||||||
|
},
|
||||||
|
selectAvatarWithConfirmation(id) {
|
||||||
|
this.$emit('select-avatar-with-confirmation', id);
|
||||||
|
},
|
||||||
|
promptClearAvatarHistory() {
|
||||||
|
this.$emit('prompt-clear-avatar-history');
|
||||||
|
},
|
||||||
|
promptNewLocalAvatarFavoriteGroup() {
|
||||||
|
this.$emit('prompt-new-local-avatar-favorite-group');
|
||||||
|
},
|
||||||
|
promptLocalAvatarFavoriteGroupRename(group) {
|
||||||
|
this.$emit('prompt-local-avatar-favorite-group-rename', group);
|
||||||
|
},
|
||||||
|
promptLocalAvatarFavoriteGroupDelete(group) {
|
||||||
|
this.$emit('prompt-local-avatar-favorite-group-delete', group);
|
||||||
|
},
|
||||||
|
renameLocalWorldFavoriteGroup(inputValue, group) {
|
||||||
|
this.$emit('rename-local-world-favorite-group', inputValue, group);
|
||||||
|
},
|
||||||
|
newLocalWorldFavoriteGroup(inputValue) {
|
||||||
|
this.$emit('new-local-world-favorite-group', inputValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="x-container">
|
<div class="x-container" v-if="menuActiveIndex === 'moderation'">
|
||||||
<data-tables
|
<data-tables
|
||||||
:data="tableData.data"
|
:data="tableData.data"
|
||||||
:pageSize="tableData.pageSize"
|
:pageSize="tableData.pageSize"
|
||||||
@@ -101,6 +101,7 @@
|
|||||||
name: 'ModerationTab',
|
name: 'ModerationTab',
|
||||||
inject: ['API', 'showUserDialog'],
|
inject: ['API', 'showUserDialog'],
|
||||||
props: {
|
props: {
|
||||||
|
menuActiveIndex: String,
|
||||||
tableData: Object,
|
tableData: Object,
|
||||||
shiftHeld: Boolean,
|
shiftHeld: Boolean,
|
||||||
hideTooltips: Boolean
|
hideTooltips: Boolean
|
||||||
|
|||||||
Reference in New Issue
Block a user