Calendar isFollowing button

This commit is contained in:
Natsumi
2025-11-07 16:50:17 +11:00
parent 18c2b42852
commit 9ef0b6fa12
4 changed files with 64 additions and 7 deletions
+15
View File
@@ -727,6 +727,21 @@ const groupReq = {
return request(`calendar/featured?date=${date}`, { return request(`calendar/featured?date=${date}`, {
method: 'GET' method: 'GET'
}); });
},
followGroupEvent(params) {
return request(`calendar/${params.groupId}/${params.eventId}/follow`, {
method: 'POST',
params: {
isFollowing: params.isFollowing
}
}).then((json) => {
const args = {
json,
params
};
return args;
});
} }
// getRequestedGroups() { // getRequestedGroups() {
@@ -277,7 +277,18 @@
} }
async function deleteAllVRChatCache() { async function deleteAllVRChatCache() {
await AssetBundleManager.DeleteAllCache(); try {
await AssetBundleManager.DeleteAllCache();
ElMessage({
message: 'All VRChat cache deleted',
type: 'success'
});
} catch (error) {
ElMessage({
message: `Error deleting VRChat cache: ${error.message}`,
type: 'error'
});
}
getVRChatCacheSize(); getVRChatCacheSize();
} }
@@ -56,20 +56,24 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="isFollowing" class="following-badge"> <div v-if="isFollowing" @click="toggleEventFollow(event)" class="following-badge is-following">
<el-icon><Check /></el-icon> <el-icon><Star /></el-icon>
</div>
<div v-else @click="toggleEventFollow(event)" class="following-badge">
<el-icon><StarFilled /></el-icon>
</div> </div>
</el-card> </el-card>
</template> </template>
<script setup> <script setup>
import { Calendar, Check, Download } from '@element-plus/icons-vue'; import { Calendar, Download, Star, StarFilled } from '@element-plus/icons-vue';
import { computed, defineEmits } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { AppDebug } from '../../../service/appConfig'; import { AppDebug } from '../../../service/appConfig';
import { formatDateFilter } from '../../../shared/utils'; import { formatDateFilter } from '../../../shared/utils';
import { groupRequest } from '../../../api';
import { useGroupStore } from '../../../stores'; import { useGroupStore } from '../../../stores';
const { t } = useI18n(); const { t } = useI18n();
@@ -96,6 +100,8 @@
} }
}); });
const emit = defineEmits(['update-following-calendar-data']);
const showGroupName = computed(() => props.mode === 'timeline'); const showGroupName = computed(() => props.mode === 'timeline');
const timeClass = computed(() => (props.mode === 'grid' ? 'event-time' : '')); const timeClass = computed(() => (props.mode === 'grid' ? 'event-time' : ''));
@@ -161,6 +167,15 @@
URL.revokeObjectURL(link.href); URL.revokeObjectURL(link.href);
} }
async function toggleEventFollow(event) {
const args = await groupRequest.followGroupEvent({
groupId: event.ownerId,
eventId: event.id,
isFollowing: !props.isFollowing
});
emit('update-following-calendar-data', args.json);
}
const formatTimeRange = (startsAt, endsAt) => const formatTimeRange = (startsAt, endsAt) =>
`${formatDateFilter(startsAt, 'time')} - ${formatDateFilter(endsAt, 'time')}`; `${formatDateFilter(startsAt, 'time')} - ${formatDateFilter(endsAt, 'time')}`;
@@ -209,7 +224,7 @@
width: 24px; width: 24px;
height: 24px; height: 24px;
border-radius: 50%; border-radius: 50%;
background-color: var(--group-calendar-badge-following, #67c23a); background-color: var(--el-text-color-regular);
color: #ffffff; color: #ffffff;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -217,6 +232,10 @@
font-size: 14px; font-size: 14px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 10; z-index: 10;
cursor: pointer;
}
.is-following {
background-color: var(--group-calendar-badge-following, #67c23a);
} }
.event-content { .event-content {
font-size: 12px; font-size: 12px;
@@ -35,7 +35,8 @@
:event="value" :event="value"
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" />
</div> </div>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
@@ -97,6 +98,7 @@
:event="event" :event="event"
mode="grid" mode="grid"
:is-following="isEventFollowing(event.id)" :is-following="isEventFollowing(event.id)"
@update-following-calendar-data="updateFollowingCalendarData"
card-class="grid-card" /> card-class="grid-card" />
</div> </div>
</div> </div>
@@ -348,6 +350,16 @@
} }
} }
function updateFollowingCalendarData(updatedEvent) {
const index = followingCalendar.value.findIndex((item) => item.id === updatedEvent.id);
if (index !== -1) {
followingCalendar.value.splice(index, 1);
}
if (updatedEvent.userInterest?.isFollowing) {
followingCalendar.value.push(updatedEvent);
}
}
function isEventFollowing(eventId) { function isEventFollowing(eventId) {
return followingCalendar.value.some((item) => item.id === eventId); return followingCalendar.value.some((item) => item.id === eventId);
} }