Group events on group dialog

This commit is contained in:
Natsumi
2025-11-19 01:41:53 +11:00
parent b1d661c086
commit 69848b6fdc
7 changed files with 173 additions and 11 deletions
+27
View File
@@ -702,6 +702,33 @@ const groupReq = {
getGroupCalendar(groupId) { getGroupCalendar(groupId) {
return request(`calendar/${groupId}`, { return request(`calendar/${groupId}`, {
method: 'GET' method: 'GET'
}).then((json) => {
const args = {
json,
params: {
groupId
}
};
return args;
});
},
/**
* @param {{
groupId: string,
eventId: string
}} params
* @return { Promise<{json: any, params}> }
*/
getGroupCalendarEvent(params) {
return request(`calendar/${params.groupId}/${params.eventId}`, {
method: 'GET'
}).then((json) => {
const args = {
json,
params
};
return args;
}); });
}, },
+4
View File
@@ -428,6 +428,10 @@ hr.x-vertical-divider {
border-radius: 2px; border-radius: 2px;
} }
.x-friend-item-no-hover:hover {
background: unset !important;
}
.x-friend-item-border:hover { .x-friend-item-border:hover {
border-top-left-radius: 25px; border-top-left-radius: 25px;
border-top-right-radius: 5px; border-top-right-radius: 5px;
@@ -546,6 +546,44 @@
> >
</div> </div>
</div> </div>
<div class="x-friend-item x-friend-item-no-hover" style="width: 100%; cursor: default">
<div class="detail" style="overflow: visible">
<span class="name">{{ t('dialog.group.info.upcoming_events') }}</span>
<template v-if="upcomingCalenderEvents.length > 0">
<br />
<div class="grid-view events-row">
<GroupCalendarEventCard
v-for="value in upcomingCalenderEvents"
:key="value.id"
:event="value"
:is-following="value.userInterest?.isFollowing"
@update-following-calendar-data="updateFollowingCalendarData"
mode="grid"
card-class="group-dialog-grid-card" />
</div>
</template>
<span v-else class="extra">-</span>
</div>
</div>
<div class="x-friend-item x-friend-item-no-hover" style="width: 100%; cursor: default">
<div class="detail" style="overflow: visible">
<span class="name">{{ t('dialog.group.info.past_events') }}</span>
<template v-if="pastCalenderEvents.length > 0">
<br />
<div class="grid-view events-row">
<GroupCalendarEventCard
v-for="value in pastCalenderEvents"
:key="value.id"
:event="value"
:is-following="value.userInterest?.isFollowing"
@update-following-calendar-data="updateFollowingCalendarData"
mode="grid"
card-class="group-dialog-grid-card" />
</div>
</template>
<span v-else class="extra">-</span>
</div>
</div>
<div class="x-friend-item" style="cursor: default"> <div class="x-friend-item" style="cursor: default">
<div class="detail"> <div class="detail">
<span class="name">{{ t('dialog.group.info.members') }}</span> <span class="name">{{ t('dialog.group.info.members') }}</span>
@@ -1147,7 +1185,7 @@
View, View,
Warning Warning
} from '@element-plus/icons-vue'; } from '@element-plus/icons-vue';
import { nextTick, reactive, ref, watch } from 'vue'; import { computed, nextTick, reactive, ref, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@@ -1173,6 +1211,7 @@
import { getNextDialogIndex } from '../../../shared/utils/base/ui'; import { getNextDialogIndex } from '../../../shared/utils/base/ui';
import { groupRequest } from '../../../api'; import { groupRequest } from '../../../api';
import GroupCalendarEventCard from '../../../views/Tools/components/GroupCalendarEventCard.vue';
import GroupPostEditDialog from './GroupPostEditDialog.vue'; import GroupPostEditDialog from './GroupPostEditDialog.vue';
import PreviousInstancesGroupDialog from '../PreviousInstancesDialog/PreviousInstancesGroupDialog.vue'; import PreviousInstancesGroupDialog from '../PreviousInstancesDialog/PreviousInstancesGroupDialog.vue';
@@ -1235,6 +1274,28 @@
roleId: '' roleId: ''
}); });
const pastCalenderEvents = computed(() => {
if (!groupDialog.value.calendar) {
return [];
}
const now = Date.now();
return groupDialog.value.calendar.filter((event) => {
const eventEnd = new Date(event.endsAt).getTime();
return eventEnd < now;
});
});
const upcomingCalenderEvents = computed(() => {
if (!groupDialog.value.calendar) {
return [];
}
const now = Date.now();
return groupDialog.value.calendar.filter((event) => {
const eventEnd = new Date(event.endsAt).getTime();
return eventEnd >= now;
});
});
watch( watch(
() => groupDialog.value.loading, () => groupDialog.value.loading,
() => { () => {
@@ -1764,4 +1825,31 @@
...obj ...obj
}; };
} }
function updateFollowingCalendarData(event) {
const calendar = groupDialog.value.calendar;
for (let i = 0; i < calendar.length; i++) {
if (calendar[i].id === event.id) {
calendar[i] = {
...calendar[i],
...event
};
break;
}
}
}
</script> </script>
<style lang="scss" scoped>
.time-group-container {
display: flex;
flex-direction: column;
gap: 8px;
overflow: visible;
}
.events-row {
display: flex;
flex-wrap: wrap;
gap: 16px;
overflow: visible;
}
</style>
+4 -2
View File
@@ -315,7 +315,7 @@
}, },
"prompt": { "prompt": {
"title": "Mutual Friend Graph", "title": "Mutual Friend Graph",
"message": "No cached mutual friend graph data was found. Start fetching now?\\nThis may take a while, we will notify you when it is finishes", "message": "No cached mutual friend graph data was found. Start fetching now? This may take a while, we will notify you when it is finishes",
"confirm": "Start Fetch", "confirm": "Start Fetch",
"cancel": "Maybe Later" "cancel": "Maybe Later"
}, },
@@ -1229,7 +1229,9 @@
"role_updated_at": "Updated At:", "role_updated_at": "Updated At:",
"role_created_at": "Created At:", "role_created_at": "Created At:",
"role_permissions": "Permissions:", "role_permissions": "Permissions:",
"last_visited": "Last Visited" "last_visited": "Last Visited",
"past_events": "Past Events",
"upcoming_events": "Upcoming Events"
}, },
"posts": { "posts": {
"header": "Posts", "header": "Posts",
+37 -1
View File
@@ -45,6 +45,7 @@ export const useGroupStore = defineStore('Group', () => {
announcement: {}, announcement: {},
posts: [], posts: [],
postsFiltered: [], postsFiltered: [],
calendar: [],
members: [], members: [],
memberSearch: '', memberSearch: '',
memberSearchResults: [], memberSearchResults: [],
@@ -141,6 +142,7 @@ export const useGroupStore = defineStore('Group', () => {
D.galleries = {}; D.galleries = {};
D.members = []; D.members = [];
D.memberFilter = groupDialogFilterOptions.everyone; D.memberFilter = groupDialogFilterOptions.everyone;
D.calendar = [];
groupRequest groupRequest
.getCachedGroup({ .getCachedGroup({
groupId groupId
@@ -461,12 +463,45 @@ export const useGroupStore = defineStore('Group', () => {
}); });
} }
}); });
groupRequest.getGroupCalendar(groupId).then((args) => {
if (groupDialog.value.id === args.params.groupId) {
D.calendar = args.json.results;
for (const event of D.calendar) {
applyGroupEvent(event);
// fetch again for isFollowing
groupRequest
.getGroupCalendarEvent({
groupId,
eventId: event.id
})
.then((args) => {
Object.assign(
event,
applyGroupEvent(args.json)
);
});
}
}
});
} }
nextTick(() => (D.isGetGroupDialogGroupLoading = false)); nextTick(() => (D.isGetGroupDialogGroupLoading = false));
return args; return args;
}); });
} }
function applyGroupEvent(event) {
return {
userInterest: {
createdAt: null,
isFollowing: false,
updatedAt: null
},
...event,
title: replaceBioSymbols(event.title),
description: replaceBioSymbols(event.description)
};
}
async function updateInGameGroupOrder() { async function updateInGameGroupOrder() {
inGameGroupOrder.value = []; inGameGroupOrder.value = [];
try { try {
@@ -1102,6 +1137,7 @@ export const useGroupStore = defineStore('Group', () => {
handleGroupRepresented, handleGroupRepresented,
showModerateGroupDialog, showModerateGroupDialog,
showGroupMemberModerationDialog, showGroupMemberModerationDialog,
onGroupLeft onGroupLeft,
applyGroupEvent
}; };
}); });
@@ -77,7 +77,7 @@
import { useGroupStore } from '../../../stores'; import { useGroupStore } from '../../../stores';
const { t } = useI18n(); const { t } = useI18n();
const { cachedGroups, showGroupDialog } = useGroupStore(); const { cachedGroups } = useGroupStore();
const props = defineProps({ const props = defineProps({
event: { event: {
@@ -100,7 +100,7 @@
} }
}); });
const emit = defineEmits(['update-following-calendar-data']); const emit = defineEmits(['update-following-calendar-data', 'click-action']);
const showGroupName = computed(() => props.mode === 'timeline'); const showGroupName = computed(() => props.mode === 'timeline');
@@ -182,7 +182,7 @@
const capitalizeFirst = (str) => str?.charAt(0).toUpperCase() + str?.slice(1); const capitalizeFirst = (str) => str?.charAt(0).toUpperCase() + str?.slice(1);
const onGroupClick = () => { const onGroupClick = () => {
showGroupDialog(props.event.ownerId); emit('click-action');
}; };
</script> </script>
@@ -203,6 +203,10 @@
flex: 0 0 280px; flex: 0 0 280px;
max-width: 280px; max-width: 280px;
} }
&.group-dialog-grid-card {
flex: 0 0 320px;
max-width: 320px;
}
:deep(.el-card__body) { :deep(.el-card__body) {
overflow: visible; overflow: visible;
} }
@@ -36,7 +36,8 @@
mode="timeline" mode="timeline"
:is-following="isEventFollowing(value.id)" :is-following="isEventFollowing(value.id)"
:card-class="{ 'grouped-card': timeGroup.events.length > 1 }" :card-class="{ 'grouped-card': timeGroup.events.length > 1 }"
@update-following-calendar-data="updateFollowingCalendarData" /> @update-following-calendar-data="updateFollowingCalendarData"
@click-action="showGroupDialog(value.ownerId)" />
</div> </div>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
@@ -99,6 +100,7 @@
mode="grid" mode="grid"
:is-following="isEventFollowing(event.id)" :is-following="isEventFollowing(event.id)"
@update-following-calendar-data="updateFollowingCalendarData" @update-following-calendar-data="updateFollowingCalendarData"
@click-action="showGroupDialog(event.ownerId)"
card-class="grid-card" /> card-class="grid-card" />
</div> </div>
</div> </div>
@@ -131,7 +133,7 @@
import GroupCalendarEventCard from '../components/GroupCalendarEventCard.vue'; import GroupCalendarEventCard from '../components/GroupCalendarEventCard.vue';
const { cachedGroups } = useGroupStore(); const { cachedGroups, applyGroupEvent, showGroupDialog } = useGroupStore();
const { t } = useI18n(); const { t } = useI18n();
@@ -341,8 +343,7 @@
try { try {
const response = await groupRequest.getFollowingGroupCalendars(dayjs(selectedDay.value).toISOString()); const response = await groupRequest.getFollowingGroupCalendars(dayjs(selectedDay.value).toISOString());
response.results.forEach((event) => { response.results.forEach((event) => {
event.title = replaceBioSymbols(event.title); applyGroupEvent(event);
event.description = replaceBioSymbols(event.description);
}); });
followingCalendar.value = response.results; followingCalendar.value = response.results;
} catch (error) { } catch (error) {