Edittext에 작성한 코드를 Discourse에 통합하는 데 도움이 필요합니다

다음 코드를 사용하여 이 타이머를 만들었습니다. 로컬에서는 잘 작동하지만 포럼에 통합하는 데 어려움을 겪고 있습니다. 도와주실 수 있나요?

<!-- HTML (이것을 헤더 섹션에 추가하세요) -->
<style>
  button {
    padding: 5px;
    margin: 2px;
    cursor: pointer;
    border: none;
    color: white;
    width: 100px; /* 모든 버튼에 원하는 폭을 설정합니다 */
    border-radius: 5px;
  }

  #readTaskButton {
    background: #008000; /* 어두운 배경에서 가독성을 높이기 위해 더 진한 초록색 */
  }

  #enterRoomButton {
    background: #DAA520; /* 더 진한 노란색 */
  }

  #pauseButton {
    background: #A0522D; /* 더 진한 주황색 */
  }

  #stopButton {
    background: #FF0000; /* 더 진한 빨간색 */
  }
</style>

<div style="display: flex; align-items: center; justify-content: center;">
  <div style="display: flex; flex-direction: column; align-items: center; margin-right: 20px;">
    <button id="readTaskButton" onclick="startTimer(90)">Read Task</button>
    <button id="enterRoomButton" onclick="startTimer(480)">Enter Room</button>
  </div>
  <div id="timer" style="font-size: 2em; text-align: center; margin: 0 20px;" onclick="togglePauseResume()">00:00</div>
  <div style="display: flex; flex-direction: column; align-items: center; margin-left: 20px;">
    <button id="pauseButton" onclick="togglePauseResume()">Pause</button>
    <button id="stopButton" onclick="stopTimer()">Stop</button>
  </div>
</div>

<!-- JavaScript (이것을 푸터 섹션에 추가하세요) -->
<script>
  let timer;
  let totalSeconds;
  let isShortTimer = true;
  let isPaused = false;

  function startTimer(duration) {
    resetTimer();
    totalSeconds = duration;
    timer = setInterval(updateTimer, 1000);
  }

  function togglePauseResume() {
    if (isPaused) {
      resumeTimer();
    } else {
      pauseTimer();
    }
    updateButtonLabel();
  }

  function updateButtonLabel() {
    const button = document.getElementById('pauseButton');
    button.innerText = isPaused ? 'Resume' : 'Pause';
  }

  function pauseTimer() {
    clearInterval(timer);
    isPaused = true;
  }

  function resumeTimer() {
    isPaused = false;
    timer = setInterval(updateTimer, 1000);
  }

  function stopTimer() {
    resetTimer();
    updateButtonLabel();
  }

  function updateTimer() {
    if (totalSeconds <= 0) {
      if (isShortTimer) {
        isShortTimer = false;
        startTimer(480); // 초기 타이머 후 더 긴 타이머를 자동으로 시작합니다
      } else {
        isShortTimer = true;
        startTimer(90); // 긴 타이머 후 초기 타이머를 자동으로 시작합니다
      }
    }

    const minutes = Math.floor(totalSeconds / 60);
    const seconds = totalSeconds % 60;

    const formattedTime = `${formatTime(minutes)}:${formatTime(seconds)}`;
    document.getElementById('timer').innerText = formattedTime;

    totalSeconds--;
  }

  function formatTime(time) {
    return time < 10 ? '0' + time : time;
  }

  function resetTimer() {
    clearInterval(timer);
    document.getElementById('timer').innerText = '00:00';
  }
</script>

안녕하세요,

작동하려면 JS를 Head에 삽입해야 합니다!
또한 button CSS에 주의하세요. 기본 CSS가 덮어쓰기되지 않도록 구체적인 선택자를 만들어야 합니다.

이상적으로는 테마 컴포넌트를 만들고, outlet을 사용해 HTML/로직을 처리하는 것이 좋습니다. 나중에 보여드릴게요!

답장 주셔서 정말 감사합니다.

말씀하신 대로 시도해 보았습니다. 새로운 테마 컴포넌트를 생성한 후, CSS/HTML 편집 옵션을 사용하여 해당 코드를 common>header 섹션에 삽입했습니다. 웹사이트에서 타이머는 확인되지만, 문제는 타이머가 작동하지 않는다는 점입니다. 재생과 정지 버튼이 있고, 로컬에서는 정상적으로 작동하지만 웹사이트에서는 타이머만 표시되고 실제 기능이 작동하지 않습니다.


콘솔도 확인해 보았고, 인스펙트(inspect)를 사용했을 때 표시되는 오류가 다음과 같습니다.

네, CSP에 의해 코드가 차단되고 있습니다. (보안 설정 참조)
설정에서 unsafe-inline를 화이트리스트에 추가할 수 있지만, 좋은 아이디어라고는 생각되지 않습니다.
귀하의 경우, CSP가 활성화된 상태에서 코드가 작동하려면 클릭 처리 방식을 다르게 해야 한다고 생각합니다.


참고로, 귀하의 코드를 사용하는 테마 컴포넌트가 있습니다: https://github.com/Arkshine/discourse-timer-component.
포크하여 Discourse에 설치하는 것을 자유롭게 하십시오.

제 코드가 너무 엉망이 아니기를 바랍니다. 이 컨텍스트에서 순수 JavaScript를 추가하는 것보다 이 방식이 권장됩니다.
추가적인 반응성 처리, 설정 및 로케일 지원도 동일하게 작동해야 합니다.

너무 부담스러울 수 있지만, 테마 컴포넌트 개발을 깊이 있게 파고들기 위한 훌륭한 기회입니다! 이해가 안 되는 부분이 있으면 주저하지 말고 질문하십시오. :slight_smile:

로컬에서 작업하려면 Discourse Theme CLI 사용을 강력히 권장합니다. 매우 편리합니다!

이렇게 도와주셔서 정말 감사드립니다. 정말 대단해요!!
덕분에 이것을 배울 영감을 얻었어요. :heart:

타이머에 대해 몇 가지 변경 사항과 질문이 있습니다. 공유해도 될까요?

질문:

  1. 대기 버튼(waiting button)의 목적은 무엇인가요?

즉시 필요한 중요한 변경 사항:

  1. 이것은 연속적인 타이머입니다. 처음에는 1분 30초로 시작하여 8분으로 전환되고, 다시 1분 30초로 전환되는 식으로 영원히 반복됩니다.

  2. 타이머가 작동 중일 때, 사용자는 ‘방 입장(enter room)’ 버튼을 클릭하여 8분으로 바로 건너뛰거나, ‘태스크 읽기(read task)’ 타이머를 클릭하여 1분 30초 타이머로 전환할 수 있어야 합니다. 따라서 타이머가 작동하지 않을 때 일시 정지 및 중지 버튼을 비활성화하는 것은 합리적이지만, 타이머가 작동 중일 때 ‘태스크 읽기’ 및 ‘방 입장’ 버튼을 비활성화하면 사용자가 타이머를 우회할 수 없게 됩니다.

향후 변경 사항:

  1. 1분 30초 타이머 시작 시, 8분 타이머 시작 시, 8분 타이머의 남은 시간 2분 시점, 그리고 8분 타이머 종료 시점(즉, 1분 30초 시작 시점)에 음성 메모를 추가합니다. 따라서 총 3개의 음성 메모가 필요합니다.
  2. 각 음성 메모마다 팝업 알림을 추가합니다. 이 알림은 나타났다가 사라져야 하며, 전체 화면을 차지하지 말고 타이머가 위치한 영역에만 표시되어야 합니다.

당신의 코드를 완전히 이해하지 못했음에 확실합니다. 그렇게 보이는 것 같습니다 :smile:

타이머가 시작되지 않은 상태에서 해당 일시정지/중단 버튼을 클릭할 수 있도록 하는 것은 의미가 없습니다. “일시정지” 또는 "재개"를 표시하는 것과도 같습니다. 마치 대기 상태에 활성 타이머가 있는 것과 같은 상황이죠. 실제로는 버튼 자체를 숨기는 것이 나을 것 같습니다. 하지만 기본값으로 “일시정지” 라벨을 사용하는 것도 괜찮을 것 같습니다.

두 가지 사이를 번갈아 가며 작동하는군요, 알겠습니다. 처음에는 그 타이머 중 하나를 가진 루프인 줄 알았어요.
컨텍스트를 정확히 이해하지 못하는 것 같고, 제 입장에서는 꽤 이상해 보입니다. 수정할 수 있습니다. :smile:

아, 그렇군요.

다른 작업을 하기 전에 먼저 그 부분을 수정하겠습니다. :slight_smile:

안녕하세요,

이 타이머가 실제로 작동하는 모습을 보니 정말 놀랍습니다. 정말 대단하고 영감을 주는 분이시네요.

이것은 의사들이 치르는 시험용 타이머입니다. 저도 의사로서 다른 의사들을 도우려고 이렇게 만들었습니다.

이 시험은 16개의 방으로 구성되어 있으며, 각 방에는 진단하고 관리해야 하는 16명의 서로 다른 환자가 있습니다. 방에 들어가기 전에, 밖에서 1분 30초 동안 읽을 수 있는 과제가 준비되어 있습니다. 이후 방에 들어가면 8분 동안 해당 과제를 수행하고 환자를 관리해야 하며, 이 과정이 나머지 15개 방에 대해 반복됩니다. 전체 소요 시간은 3시간입니다.

저는 불행히도 이 시험에 떨어졌는데, 그 이유는 이 시험에 대한 잘못된 정보와 잘못된 안내 때문이었습니다. 이 경험이 다른 의사들을 올바르게 안내하기 위해 이 포럼을 만들게 된 계기가 되었습니다.

이 설명이 배경을 이해하는 데 도움이 되기를 바랍니다. :innocent:

업데이트를 푸시했습니다. 이제 short/long 타이머가 순환하며, 어떤 타이머로든 전환할 수 있습니다. 또한 “waiting..” 사용도 제거했습니다. 더 잘 작동하는지 알려주세요.

컨텍스트를 설명해 주셔서 감사합니다. 이제 이해했습니다! :+1:

버그를 발견했습니다. 읽기 작업 버튼을 클릭하면 타이머가 1분 30초에서 8분으로 바뀌고, 이후 1분 30초로 계속 반복됩니다. 방 입장 버튼을 클릭하면 타이머가 8분에서 1분 30초로 바뀌고, 이후 8분 타이머로 계속 반복됩니다.

죄송합니다. 수정했습니다. 서두르고 있어서 첫 번째 루프만 확인했고, 이후에 스위칭이 일어나지 않는 것을 놓쳤습니다. :smile:

괜찮아요!

앞서 공유해 주신 자료도 함께 공부할게요. 궁금한 점이 생기면 다시 말씀드릴게요.

현재 문제는 “작업 읽기” 버튼을 클릭하면 타이머가 1:30에서 시작하여 8:00에서 반복된다는 점입니다.

1:30 > 8:00 > 8:00 > 8:00 ..

“방 입장” 버튼을 클릭하면 타이머가 8:00에서 시작하여 1:30에서 반복됩니다.

8:00 > 1:30 > 1:30 > 1:30 ..

이상적으로는 처음 클릭한 버튼에 따라 시작 지점이 결정되며, 1:30과 8:00 사이를 번갈아 가며 부드럽게 연속되는 루프가 형성되어야 합니다.

예를 들어, “작업 읽기” 버튼을 클릭하면 타이머는 1:30에서 시작하여 8:00과 1:30 사이를 번갈아 가며 진행되어야 합니다:

1:30 > 8:00 > 1:30 > 8:00..

“방 입장” 버튼을 클릭하면 타이머는 8:00에서 시작하여 1:30과 8:00 사이를 번갈아 가며 진행되어야 합니다:

8:00 > 1:30 > 8:00 > 1:30..

업데이트와 페이지 새로 고침을 정말로 수행하셨나요? 수정 전 버그를 설명하셨고, 지금은 재현할 수 없습니다. 다시 테스트해 보니 예상대로 루프가 정상적으로 작동합니다.

방금 확인해봤는데, 예상대로 잘 작동하고 있어요. :innocent::heart:

이제 타이머에 직접 변경 사항을 적용하는 방법을 배우고 싶습니다. 그래서 더 이상 귀찮게 하지 않을게요. :joy:

기존의 이 타이머 프로젝트를 활용해 저에게 작은 과제를 하나 만들어 주었으면 좋겠어요. 이를 통해 학습을 도울 수 있을 것 같습니다.

과제는 실제 타이머 바로 위에 "PLAB 2 Timer"라는 이름을 추가하는 것입니다. 아래 이미지와 같이요:

어디서부터 시작해야 할지 안내해 주실 수 있나요?

첫 번째 단계는 개발용 Discourse를 설치하는 것입니다. 이렇게 하면 테스트가 더 쉬워집니다.

그 다음, 제 컴포넌트를 포크하고 어딘가에 클론한 후 Discourse Theme CLI를 사용할 수 있습니다.

<template>... </template> 코드를 확인해 보세요. 여기에 텍스트를 추가할 수 있습니다.
CSS는 common/common.scss 파일에 있습니다.

locales/en.yml에 항목을 추가하여 텍스트를 로컬라이즈할 수 있습니다. 그러면 {{I18n.t(themePrefix("my_translation_key"))}}를 사용할 수 있습니다.