`)
- fragment.appendChild(timetable?.firstChild!)
-
- // Create upcoming assessments section
- const upcomingContainer = document.createElement('div')
- upcomingContainer.classList.add('upcoming-container', 'border')
-
- const upcomingTitleDiv = CreateElement('div', 'upcoming-title')
- const upcomingTitle = document.createElement('h2')
- upcomingTitle.classList.add('home-subtitle')
- upcomingTitle.innerText = 'Upcoming Assessments'
- upcomingTitleDiv.append(upcomingTitle)
-
- const upcomingFilterDiv = CreateElement('div', 'upcoming-filters', 'upcoming-filters')
- upcomingTitleDiv.append(upcomingFilterDiv)
- upcomingContainer.append(upcomingTitleDiv)
-
- const upcomingItems = document.createElement('div')
- upcomingItems.id = 'upcoming-items'
- upcomingItems.classList.add('upcoming-items')
- upcomingContainer.append(upcomingItems)
- fragment.appendChild(upcomingContainer)
-
- // Create notices section
- const notices = stringToHTML(`
-
-
-
Notices
-
+
+
+
Upcoming Assessments
+
+
+
+
+
+
-
`)
- fragment.appendChild(notices?.firstChild!)
- // Single DOM update to home-container
- homeContainer.appendChild(fragment)
+ // Add skeleton structure
+ homeContainer.appendChild(skeletonStructure.firstChild!)
+
+ // Run animations if enabled
+ if (settingsState.animations) {
+ animate(
+ '.home-container > div',
+ { opacity: [0, 1], y: [10, 0], scale: [0.99, 1] },
+ {
+ delay: stagger(0.15, { startDelay: 0.1 }),
+ type: 'spring',
+ stiffness: 341,
+ damping: 20,
+ mass: 1
+ }
+ )
+ }
// Setup event listeners with cleanup
const cleanup = setupTimetableListeners()
+ // Initialize shortcuts immediately
+ addShortcuts(settingsState.shortcuts)
+ AddCustomShortcutsToPage()
+
// Parallel data fetching
const [assessments, classes, prefs] = await Promise.all([
GetUpcomingAssessments(),
@@ -2272,10 +2252,20 @@ export async function loadHomePage() {
.sort(comparedate)
// Initialize components
- addShortcuts(settingsState.shortcuts)
- AddCustomShortcutsToPage()
+ const date = new Date()
+ const TodayFormatted = formatDate(date)
+
+ // Load timetable
await callHomeTimetable(TodayFormatted, true)
- await CreateUpcomingSection(currentAssessments, activeSubjects)
+
+ // Load upcoming assessments
+ const upcomingItems = document.getElementById('upcoming-items')
+ if (upcomingItems) {
+ await CreateUpcomingSection(currentAssessments, activeSubjects)
+ delay(100)
+ upcomingItems.classList.remove('loading')
+ console.log('Upcoming assessments created')
+ }
// Setup notices
const labelArray = prefs.payload
@@ -2283,32 +2273,17 @@ export async function loadHomePage() {
.map((item: any) => item.value)
if (labelArray.length > 0) {
- setupNotices(labelArray[0].split(' '), TodayFormatted)
+ const noticeContainer = document.getElementById('notice-container')
+ if (noticeContainer) {
+ noticeContainer.classList.remove('loading')
+ setupNotices(labelArray[0].split(' '), TodayFormatted)
+ }
}
if (settingsState.notificationcollector) {
enableNotificationCollector()
}
- // Setup animations
- if (settingsState.animations) {
- // Remove the initial style
- document.head.querySelector('style:last-child')?.remove()
-
- // Animate with motion
- animate(
- '.home-container > div',
- { opacity: [0, 1], y: [10, 0], scale: [0.99, 1] },
- {
- delay: stagger(0.15, { startDelay: 0.1 }),
- type: 'spring',
- stiffness: 341,
- damping: 20,
- mass: 1
- }
- )
- }
-
return cleanup
}
diff --git a/src/css/injected.scss b/src/css/injected.scss
index da9ad98e..aa77acca 100644
--- a/src/css/injected.scss
+++ b/src/css/injected.scss
@@ -2724,7 +2724,7 @@ li.MessageList__unread___3imtO {
display: flex;
flex-direction: column;
color: var(--text-primary);
- transition: 200ms;
+ transition: 200ms, background-color 0s;
border-radius: 16px;
}
.dark .upcoming-items {
@@ -3093,4 +3093,30 @@ li.MessageList__unread___3imtO {
aspect-ratio: 16/9;
object-fit: cover;
margin-bottom: 12px;
-}
\ No newline at end of file
+}
+
+@keyframes shimmer {
+ 0% {
+ background-position: -1000px 0;
+ }
+ 100% {
+ background-position: 1000px 0;
+ }
+}
+
+.loading {
+ &.upcoming-items,
+ &.day-container {
+ background: linear-gradient(90deg,
+ var(--background-primary) 0%,
+ var(--background-secondary) 50%,
+ var(--background-primary) 100%
+ );
+ background-size: 1000px 100%;
+ animation: shimmer 2s infinite linear;
+ }
+
+ &.upcoming-items {
+ height: 35em;
+ }
+}