Codex commited on
Commit
8c3a0fd
·
1 Parent(s): 0855e12

Polish weekly course cards

Browse files
Files changed (2) hide show
  1. static/planner.js +84 -7
  2. static/v020.css +56 -5
static/planner.js CHANGED
@@ -347,6 +347,51 @@
347
  return `第${String(index + 1).padStart(2, "0")}节`;
348
  }
349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  function decorateScheduleItems(items) {
351
  const grouped = new Map();
352
 
@@ -638,14 +683,24 @@
638
  if (item.color) {
639
  block.style.setProperty("--event-accent", item.color);
640
  }
 
 
 
 
 
 
 
 
 
641
  block.innerHTML = `
642
- <div class="planner-event-top">
643
- <strong>${escapeHtml(item.title)}</strong>
644
- <span class="planner-lock-badge">固定课程</span>
645
- </div>
646
- <div class="planner-event-meta">
647
- <span class="planner-event-time">${escapeHtml(item.start_time)} - ${escapeHtml(item.end_time)}</span>
648
- <span>${escapeHtml(item.location || "")}</span>
 
649
  </div>
650
  `;
651
  } else {
@@ -920,6 +975,28 @@
920
  if (item.color) {
921
  block.style.setProperty("--event-accent", item.color);
922
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
923
  block.innerHTML = `
924
  <div class="planner-event-top">
925
  <strong>${escapeHtml(item.title)}</strong>
 
347
  return `第${String(index + 1).padStart(2, "0")}节`;
348
  }
349
 
350
+ function getCoursePeriodRange(startTime, endTime) {
351
+ const slots = state.planner.time_slots || [];
352
+ let startPeriod = null;
353
+ let endPeriod = null;
354
+
355
+ slots.forEach((slot, index) => {
356
+ const slotIndex = index + 1;
357
+ if (slot.start === startTime) {
358
+ startPeriod = slotIndex;
359
+ }
360
+ if (slot.end === endTime) {
361
+ endPeriod = slotIndex;
362
+ }
363
+ });
364
+
365
+ if (startPeriod === null || endPeriod === null) {
366
+ const startMinutes = toMinutes(startTime);
367
+ const endMinutes = toMinutes(endTime);
368
+ slots.forEach((slot, index) => {
369
+ const slotStart = toMinutes(slot.start);
370
+ const slotEnd = toMinutes(slot.end);
371
+ if (startPeriod === null && startMinutes <= slotStart && startMinutes < slotEnd) {
372
+ startPeriod = index + 1;
373
+ }
374
+ if (slotStart < endMinutes && endMinutes <= slotEnd) {
375
+ endPeriod = index + 1;
376
+ }
377
+ });
378
+ }
379
+
380
+ if (startPeriod !== null && endPeriod !== null) {
381
+ return startPeriod === endPeriod ? `第${startPeriod}节` : `${startPeriod}-${endPeriod}节`;
382
+ }
383
+ return `${startTime} - ${endTime}`;
384
+ }
385
+
386
+ function getCourseWeekText(item) {
387
+ const patternLabel = item.week_pattern === "odd"
388
+ ? " 单周"
389
+ : item.week_pattern === "even"
390
+ ? " 双周"
391
+ : "";
392
+ return `${item.start_week}-${item.end_week}周${patternLabel}`;
393
+ }
394
+
395
  function decorateScheduleItems(items) {
396
  const grouped = new Map();
397
 
 
683
  if (item.color) {
684
  block.style.setProperty("--event-accent", item.color);
685
  }
686
+ const courseWeekText = getCourseWeekText(item);
687
+ const coursePeriodText = getCoursePeriodRange(item.start_time, item.end_time);
688
+ const courseLines = [
689
+ courseWeekText,
690
+ coursePeriodText,
691
+ item.location || "",
692
+ `${item.start_time} - ${item.end_time}`,
693
+ ].filter(Boolean);
694
+ block.title = [item.title, ...courseLines].join("\n");
695
  block.innerHTML = `
696
+ <div class="planner-course-stack">
697
+ <strong class="planner-course-title">${escapeHtml(item.title)}</strong>
698
+ <div class="planner-course-details">
699
+ <span class="planner-course-line">${escapeHtml(courseWeekText)}</span>
700
+ <span class="planner-course-line">${escapeHtml(coursePeriodText)}</span>
701
+ <span class="planner-course-line">${escapeHtml(item.location || "")}</span>
702
+ <span class="planner-course-line planner-event-time">${escapeHtml(item.start_time)} - ${escapeHtml(item.end_time)}</span>
703
+ </div>
704
  </div>
705
  `;
706
  } else {
 
975
  if (item.color) {
976
  block.style.setProperty("--event-accent", item.color);
977
  }
978
+ const courseWeekText = getCourseWeekText(item);
979
+ const coursePeriodText = getCoursePeriodRange(item.start_time, item.end_time);
980
+ const courseLines = [
981
+ courseWeekText,
982
+ coursePeriodText,
983
+ `${item.start_time} - ${item.end_time}`,
984
+ item.location || "",
985
+ ].filter(Boolean);
986
+ block.title = [item.title, ...courseLines].join("\n");
987
+ block.innerHTML = `
988
+ <div class="planner-course-stack">
989
+ <strong class="planner-course-title">${escapeHtml(item.title)}</strong>
990
+ <div class="planner-course-details">
991
+ <span class="planner-course-line">${escapeHtml(courseWeekText)}</span>
992
+ <span class="planner-course-line">${escapeHtml(coursePeriodText)}</span>
993
+ <span class="planner-course-line planner-event-time">${escapeHtml(item.start_time)} - ${escapeHtml(item.end_time)}</span>
994
+ <span class="planner-course-line">${escapeHtml(item.location || "")}</span>
995
+ </div>
996
+ </div>
997
+ `;
998
+ canvasLayer.appendChild(block);
999
+ return;
1000
  block.innerHTML = `
1001
  <div class="planner-event-top">
1002
  <strong>${escapeHtml(item.title)}</strong>
static/v020.css CHANGED
@@ -582,6 +582,40 @@ body.planner-interacting .page-planner {
582
  font-size: 0.74rem;
583
  }
584
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  .planner-lock-badge,
586
  .planner-event-clear,
587
  .planner-task-clear {
@@ -634,6 +668,10 @@ body.planner-interacting .page-planner {
634
  z-index: 8;
635
  }
636
 
 
 
 
 
637
  .planner-event.is-compact {
638
  border-radius: 16px;
639
  padding: 7px 10px 8px;
@@ -657,13 +695,17 @@ body.planner-interacting .page-planner {
657
  display: none;
658
  }
659
 
660
- .course-event.is-compact .planner-event-meta {
661
- margin-top: 4px;
662
- font-size: 0.76rem;
663
  }
664
 
665
- .course-event.is-compact .planner-event-meta span:last-child {
666
- display: none;
 
 
 
 
 
667
  }
668
 
669
  .planner-event.is-tight {
@@ -677,6 +719,15 @@ body.planner-interacting .page-planner {
677
  display: none;
678
  }
679
 
 
 
 
 
 
 
 
 
 
680
  .planner-event.is-tight .planner-event-top {
681
  display: block;
682
  }
 
582
  font-size: 0.74rem;
583
  }
584
 
585
+ .planner-course-stack {
586
+ display: grid;
587
+ gap: 2px;
588
+ min-height: 100%;
589
+ }
590
+
591
+ .planner-course-title {
592
+ display: block;
593
+ margin: 0;
594
+ font-size: 0.72rem;
595
+ line-height: 1.08;
596
+ letter-spacing: 0.01em;
597
+ word-break: break-word;
598
+ overflow: hidden;
599
+ display: -webkit-box;
600
+ -webkit-box-orient: vertical;
601
+ -webkit-line-clamp: 2;
602
+ }
603
+
604
+ .planner-course-details {
605
+ display: grid;
606
+ gap: 1px;
607
+ color: rgba(238, 244, 251, 0.82);
608
+ font-size: 0.56rem;
609
+ line-height: 1.08;
610
+ }
611
+
612
+ .planner-course-line {
613
+ display: block;
614
+ white-space: normal;
615
+ overflow-wrap: anywhere;
616
+ font-variant-numeric: tabular-nums;
617
+ }
618
+
619
  .planner-lock-badge,
620
  .planner-event-clear,
621
  .planner-task-clear {
 
668
  z-index: 8;
669
  }
670
 
671
+ .course-event {
672
+ padding: 7px 8px 7px 10px;
673
+ }
674
+
675
  .planner-event.is-compact {
676
  border-radius: 16px;
677
  padding: 7px 10px 8px;
 
695
  display: none;
696
  }
697
 
698
+ .course-event.is-compact .planner-course-stack {
699
+ gap: 2px;
 
700
  }
701
 
702
+ .course-event.is-compact .planner-course-title {
703
+ font-size: 0.68rem;
704
+ }
705
+
706
+ .course-event.is-compact .planner-course-details {
707
+ gap: 1px;
708
+ font-size: 0.54rem;
709
  }
710
 
711
  .planner-event.is-tight {
 
719
  display: none;
720
  }
721
 
722
+ .course-event.is-tight .planner-course-details {
723
+ display: none;
724
+ }
725
+
726
+ .course-event.is-tight .planner-course-title {
727
+ font-size: 0.62rem;
728
+ line-height: 1.06;
729
+ }
730
+
731
  .planner-event.is-tight .planner-event-top {
732
  display: block;
733
  }