diff --git a/js/audio-service.ts b/js/audio-service.ts index 44dc4a8..7e6cc0c 100644 --- a/js/audio-service.ts +++ b/js/audio-service.ts @@ -4,7 +4,7 @@ import BackgroundTimer, {IntervalId} from 'react-native-background-timer'; import { genAutopause, genUpdateProgressForLesson, - genMarkLessonFinished, + genMarkLesson, genPreferenceStreamQuality, } from './persistence'; import CourseData from './course-data'; @@ -272,7 +272,7 @@ export default async () => { course: wasPlaying?.course, lesson: wasPlaying?.lesson, }); - await genMarkLessonFinished(wasPlaying.course, wasPlaying.lesson); + await genMarkLesson(wasPlaying.course, wasPlaying.lesson, true); await genUpdateProgressForLesson( wasPlaying.course, wasPlaying.lesson, @@ -327,7 +327,7 @@ export default async () => { // guess who worked out the hard way that if you do the next two concurrently you get a race condition - await genMarkLessonFinished(wasPlaying.course, wasPlaying.lesson); + await genMarkLesson(wasPlaying.course, wasPlaying.lesson, true); // otherwise it's very tricky to play it again! await genUpdateProgressForLesson( diff --git a/js/components/AllLessons/LessonRow.react.tsx b/js/components/AllLessons/LessonRow.react.tsx index 6d58edb..2fa3964 100644 --- a/js/components/AllLessons/LessonRow.react.tsx +++ b/js/components/AllLessons/LessonRow.react.tsx @@ -5,7 +5,7 @@ import ProgressCircle from 'react-native-progress-circle'; import {Icon} from 'react-native-elements'; import formatDuration from 'format-duration'; import prettyBytes from 'pretty-bytes'; -import {genProgressForLesson, Progress} from '../../persistence'; +import {genMarkLesson, genProgressForLesson, Progress} from '../../persistence'; import DownloadManager, {useDownloadStatus} from '../../download-manager'; import CourseData from '../../course-data'; import {usePreference} from '../../persistence'; @@ -166,10 +166,33 @@ const LessonRow = ({ const finished = progress?.finished; const downloading = downloadState && !downloadState.error && !downloadState.finished; - - const bundled = !!(lesson === 0 && CourseData.getBundledFirstLesson(course)) + + const bundled = !!(lesson === 0 && CourseData.getBundledFirstLesson(course)); + + const handleFinishedPress = async () => { + log({ + action: `mark_${finished ? 'unfinished' : 'finished'}`, + surface: 'all_lessons', + course, + lesson, + }); + await genMarkLesson(course, lesson, !finished); + setProgress({...progress!, finished: !finished}); + }; + return ( + + + + + { navigate('Listen', {course, lesson}); @@ -177,16 +200,6 @@ const LessonRow = ({ {ready ? ( - {CourseData.getLessonTitle(course, lesson)} @@ -234,12 +247,11 @@ const LessonRow = ({ const styles = StyleSheet.create({ row: { flexDirection: 'row', - }, - lessonBox: { - paddingHorizontal: 20, backgroundColor: 'white', borderBottomColor: '#ccc', borderBottomWidth: 1, + }, + lessonBox: { flex: 1, flexDirection: 'row', justifyContent: 'space-between', @@ -247,9 +259,6 @@ const styles = StyleSheet.create({ downloadBox: { width: LESSON_ROW_HEIGHT, height: LESSON_ROW_HEIGHT, - backgroundColor: 'white', - borderColor: '#ccc', - borderBottomWidth: 1, alignItems: 'center', justifyContent: 'center', }, @@ -269,10 +278,6 @@ const styles = StyleSheet.create({ fontSize: 12, color: 'gray', }, - - finishedIcon: { - marginRight: 24, - }, progressCircleText: { fontSize: 16, }, diff --git a/js/components/Listen/ListenBottomSheet.react.tsx b/js/components/Listen/ListenBottomSheet.react.tsx index 58396a6..8bc2cbd 100644 --- a/js/components/Listen/ListenBottomSheet.react.tsx +++ b/js/components/Listen/ListenBottomSheet.react.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect, useState} from 'react'; import { StyleSheet, View, @@ -9,41 +9,52 @@ import { import {Icon} from 'react-native-elements'; import CourseData from '../../course-data'; import DownloadManager from '../../download-manager'; -import {genMarkLessonFinished} from '../../persistence'; +import {genMarkLesson, genProgressForLesson, Progress} from '../../persistence'; import {genStopPlaying} from '../../audio-service'; import {useNavigation} from '@react-navigation/native'; import {useProgress} from 'react-native-track-player'; import {log} from '../../metrics'; import formatDuration from 'format-duration'; -import { MainNavigationProp } from '../App.react'; +import {MainNavigationProp} from '../App.react'; interface Props { - course: Course, - lesson: number, + course: Course; + lesson: number; downloaded: boolean | null; } const ListenBottomSheet = ({course, lesson, downloaded}: Props) => { const {position} = useProgress(); const {pop} = useNavigation>(); + const [progress, setProgress] = useState(null); + + useEffect(() => { + (async () => { + const progressResp = await genProgressForLesson(course, lesson); + setProgress(progressResp); + })(); + }, [course, lesson]); + + const finished = progress?.finished; return ( <> { log({ - action: 'mark_finished', + action: `mark_${finished ? 'unfinished' : 'finished'}`, surface: 'listen_bottom_sheet', course, lesson, position, }); - - await genMarkLessonFinished(course, lesson); + await genMarkLesson(course, lesson, !finished); pop(); }}> - Mark as finished + {`Mark as ${ + finished ? 'unfinished' : 'finished' + }`} => { const progressObject = await genProgressForLesson(course, lesson); @@ -103,7 +104,7 @@ export const genMarkLessonFinished = async ( `@activity/${course}/${lesson}`, JSON.stringify({ ...progressObject, - finished: true, + finished, }), ), AsyncStorage.setItem( @@ -114,6 +115,7 @@ export const genMarkLessonFinished = async ( ]); if ( + finished && (await genPreferenceAutoDeleteFinished()) && (await DownloadManager.genIsDownloaded(course, lesson)) ) {