Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio upload fixes #1266

Merged
merged 2 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css } from "@emotion/css"
import { useRouter } from "next/router"
import React, { RefObject } from "react"
import React, { RefObject, useContext } from "react"

import PageContext from "../../../../contexts/PageContext"
import { headingFont } from "../../../../shared-module/styles"
import { AudioFile } from "../../../Page"

Expand All @@ -13,6 +13,7 @@ interface DisplayTrackProps {
}

const DisplayTrack = ({ tracks, audioRef, setDuration, progressBarRef }: DisplayTrackProps) => {
const pageContext = useContext(PageContext)
const onLoadedMetadata = () => {
if (audioRef?.current && progressBarRef?.current) {
const seconds = audioRef?.current?.duration
Expand All @@ -21,12 +22,6 @@ const DisplayTrack = ({ tracks, audioRef, setDuration, progressBarRef }: Display
}
}

const router = useRouter()

const title = router.asPath.split("/")[5]
let formattedTitle = title.charAt(0).toUpperCase() + title.slice(1)
formattedTitle = formattedTitle.replace(/-/g, " ")

return (
<>
<div>
Expand Down Expand Up @@ -60,7 +55,7 @@ const DisplayTrack = ({ tracks, audioRef, setDuration, progressBarRef }: Display
text-overflow: ellipsis;
`}
>
{formattedTitle}
{pageContext.pageData?.title}
</p>
</div>
</div>
Expand Down
10 changes: 9 additions & 1 deletion services/course-material/src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ const Page: React.FC<React.PropsWithChildren<Props>> = ({ onRefresh, organizatio
justify-content: center;
align-items: center;
gap: 0 5px;

cursor: pointer;
filter: brightness(1) contrast(1);
transition: filter 0.3s;

&:hover {
filter: brightness(0.9) contrast(1.1);
}
`}
>
<AudioSpeaker />
Expand All @@ -216,7 +224,7 @@ const Page: React.FC<React.PropsWithChildren<Props>> = ({ onRefresh, organizatio
color: #fff;
`}
>
{t("audio-player")}
{t("open-audio-player-button")}
</span>
</button>
</AudioNotification>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,21 @@ pub async fn seed_organization_uh_mathstat(
)
.await?;

let audio_course = seed_sample_course(
Uuid::parse_str("2b80a0cb-ae0c-4f4b-843e-0322a3d18aff")?,
"Audio course",
"audio-course",
uh_data.clone(),
)
.await?;

roles::insert(
&mut conn,
teacher_user_id,
UserRole::Teacher,
RoleDomain::Course(audio_course),
)
.await?;

Ok(uh_mathstat_id)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ import { primaryFont } from "../../../../../../../shared-module/styles"
import { respondToOrLarger } from "../../../../../../../shared-module/styles/respond"
import { runCallbackIfEnterPressed } from "../../../../../../../shared-module/utils/accessibility"

const ACCEPTABLE_MIME_TYPES = [
"audio/mpeg",
"audio/ogg",
// Some audio files are detected as video/ogg even though they are audio files
"video/ogg",
]

export interface AudioUploadAttributes {
id: string | null
open: boolean
Expand Down Expand Up @@ -82,15 +89,16 @@ const PageAudioWidget: React.FC<React.PropsWithChildren<AudioUploadAttributes>>
)

const handleUpload = (event: React.ChangeEvent<HTMLFormElement>) => {
event.preventDefault()
if (!event.currentTarget.audioFile) {
return
}
const file: File | null = event.currentTarget.audioFile.files[0]

if (file) {
const isNotAcceptedFormat = file.type !== "audio/mpeg" && file.type !== "audio/ogg"
if (isNotAcceptedFormat) {
if (!ACCEPTABLE_MIME_TYPES.includes(file.type)) {
console.error("The audio format is not accepted")
throw new Error("The audio format is not accepted")
}
uploadAudioFileMutation.mutate(file)
event.currentTarget.audioFile.value = null
Expand Down Expand Up @@ -226,6 +234,8 @@ const PageAudioWidget: React.FC<React.PropsWithChildren<AudioUploadAttributes>>
)}
<form
onSubmit={handleUpload}
method="POST"
encType="multipart/form-data"
className={css`
margin-top: 20px;
border: 1px solid #555;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const PageListItem: React.FC<React.PropsWithChildren<PageListItemProps>> = ({
href: `/manage/pages/${page.id}/history`,
},
{
label: t("upload-file"),
label: t("upload-audio-file"),
// eslint-disable-next-line i18next/no-literal-string
onClick: () => {
setShowDialog(true)
Expand Down
2 changes: 1 addition & 1 deletion shared-module/src/locales/en/course-material.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"american-english": "English",
"attempted-exercises-required-for-completion": "Attempted exercises required for completion",
"audio-notification-description": "Hear the current page content read aloud",
"audio-player": "Listen",
"author": "Authors",
"available-in-languages": "Available in {{num}} languages",
"available-on-date-at-time": "Available {{ date }} at {{ time }}",
Expand Down Expand Up @@ -114,6 +113,7 @@
"no-comments-yet": "No comments yet",
"no-submission-received-for-this-exercise": "No submission received for this exercise.",
"number-of-student": "Number of students",
"open-audio-player-button": "Listen",
"opens-in-time": "Opens in {{ relative-time }}",
"opens-now": "Opens now!",
"peer-review": "Peer review",
Expand Down
2 changes: 1 addition & 1 deletion shared-module/src/locales/en/main-frontend.json
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@
"updated-definition": "Updated definition",
"updated-term": "Updated term",
"upload": "Upload",
"upload-file": "Upload file",
"upload-audio-file": "Upload audio file",
"url": "URL",
"use-this-email-address-on-the-registration-form": "Use this email address on the enrollment form",
"user-answer-explanation": "This is the data that gets sent to the server to be graded when user answers an exercise. You can fill this data from the answer-exercise view by submitting the exercise.",
Expand Down
2 changes: 1 addition & 1 deletion shared-module/src/locales/fi/course-material.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"american-english": "Englanti",
"attempted-exercises-required-for-completion": "Yritettyjä tehtäviä vaaditaan läpipääsyyn",
"audio-notification-description": "Kuuntele tämän sivun sisältö ääneen luettuna",
"audio-player": "Kuuntele",
"author": "Kirjoittajat",
"available-in-languages": "Saatavilla {{num}} kielellä",
"available-on-date-at-time": "Avoinna {{ date }} klo {{ time }}",
Expand Down Expand Up @@ -116,6 +115,7 @@
"no-comments-yet": "Ei kommentteja vielä",
"no-submission-received-for-this-exercise": "Tähän tehtävään ei ole vastattu.",
"number-of-student": "Opiskelijoiden määrä",
"open-audio-player-button": "Kuuntele",
"opens-in-time": "Avautuu {{ relative-time }}",
"opens-now": "Avautuu nyt!",
"page": "Sivu",
Expand Down
2 changes: 1 addition & 1 deletion shared-module/src/locales/fi/main-frontend.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@
"updated-definition": "Uusi määritelmä",
"updated-term": "Uusi termi",
"upload": "Lisää",
"upload-file": "Lisää tiedosto",
"upload-audio-file": "Lisää äänitiedosto",
"url": "URL",
"use-this-email-address-on-the-registration-form": "Käytä tätä sähköpostiosoitetta suorituksen kirjaamiseen",
"user-answer-explanation": "Tämä data lähetetään palvelimelle arvosteltavaksi kun oppilas vastaa tehtävään. Voit täyttää tämän kentän answer-execise näkymästä lähettämällä tehtävän.",
Expand Down
Binary file added system-tests/src/fixtures/media/audio.ogg
Binary file not shown.
35 changes: 35 additions & 0 deletions system-tests/src/tests/audio.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { test } from "@playwright/test"

import { selectCourseInstanceIfPrompted } from "../utils/courseMaterialActions"

test.use({
storageState: "src/states/[email protected]",
})

test("Can upload audio files to pages", async ({ page }) => {
await page.goto("http://project-331.local/")
await page.getByRole("link", { name: "All organizations" }).click()
await page.getByLabel("University of Helsinki, Department of Mathematics and Statistics").click()
await page.getByLabel("Manage course 'Audio course'").click()
await page.getByRole("tab", { name: "Pages" }).click()
await page
.getByRole("row", { name: "The Basics /chapter-1 Edit" })
.getByLabel("Dropdown menu")
.click()
await page.getByRole("button", { name: "Upload audio file" }).click()
const [fileChooser] = await Promise.all([
page.waitForEvent("filechooser"),
page.locator("#audioFile").click(),
])
await fileChooser.setFiles("src/fixtures/media/audio.ogg")
await page.getByRole("button", { name: "Upload" }).click()
await page.getByText("Success").first().waitFor()
await page.getByText("audio/ogg").waitFor()

// Test that the player is there
await page.goto("http://project-331.local/org/uh-mathstat/courses/audio-course")
await selectCourseInstanceIfPrompted(page)
await page.getByRole("link", { name: "Chapter 1 The Basics" }).click()
await page.getByRole("button", { name: "Listen" }).click()
await page.getByText("00:00").first().waitFor()
})
Loading