Giter VIP home page Giter VIP logo

lt-app's People

Contributors

aarefabrik avatar dependabot[bot] avatar gabrfarina avatar jafayer avatar schonfeld avatar syntaxblitz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lt-app's Issues

Internationalization

Since the app includes a course for Spanish speakers, it'd be nice to use localized text in the app, at least in Spanish.

Tasks:

  • Wrap all text rendering in a localization function
    • I tend to prefer keeping the text literal in the code (like in fbt, which -- come to think of it -- is open source), rather than replacing text with some constant that you need to look up in another file. This does introduce a few headaches, but I still like it for its greppability and (more importantly) code readability.
    • Don't forget accessibility labels and alt-texts
  • Get Spanish-translated versions of all strings. Mihalis may be able to help, or any volunteer.

Automatically fetch course metadata updates

Right now, a course's metadata is only refreshed if the user manually refreshes the metadata (or clears the course data entirely). If corrections need to be shipped, especially for auto-pause data, it'd be nice to ship them automatically.

We store the download time of each course's metadata. This means we could easily invalidate metadata that's more than, say, a week old. Another option would be to store each course's most recent metadata version somewhere on the server in case we don't want the user to have to re-download the entire course metadata each time. For now, it's not a huge deal, but if we store auto-pause information in the course metadata, these files may get to a few hundred kilobytes, which we may not want to download willy-nilly (since we do these downloads over mobile data without asking, even if lesson audio is configured to download only over wifi).

Refactor the additionalButton into its own component

There are a few places in the app where we pretty much use exactly the same markup and styling to make a button. This is a remnant from when I was just prototyping and didn't want to put in the effort to keep it DRY. Let's extract that into its own component.

map bluetooth rewind button to rewind 10 seconds

Hi,

Thank you very much for this great app!
Wanted to ask if it is possible to map the bluetooth rewind button signal to rewind 10 seconds in the current lesson (like in podcast apps and such).
Currently pressing this button (from car bluetooth controls, for example), doesn't do anything.

Cleanup: use arrays instead of object deconstruction for multi-styles

A StackOverflow post lied to me and told me that {...styles.one, ...styles.two} was the "best" way to merge styles. Later I found out you can just pass in an array: [styles.one, styles.two] which seems a lot better (this is my first react native app!!). We should clean up instances of the former.

iOS 14: Can’t Rewind 10s if Paused

I'm really loving this app and these courses so far, so thank you to everyone that worked on it! Now, there is an issue with the 'rewind 10s' button. It only works when playing, it will not seek back 10s when it is paused. I'm testing/using lt-app on an iPhone SE 2020.

Better accessibility for formatDuration results

Right now, anywhere we call formatDuration is kind of a crappy user experience for the visually impaired. "5:12" will be spoken aloud as "five colon twelve".

We should make a wrapper for this type of text, or at least a function that "renders" this in words, so that screen readers don't choke on this.

To test:

  • Enable TalkBack
  • Touch some durations

Add rating prompt on iOS

This code is in js/components/LanguageHome/LanguageHomeTopButton.react.tsx.

Will require:

  • updating the log action name
  • updating the linked URL and testing that this behaves acceptably in iOS
  • checking App Store policies about rating prompts; do we need to do this with some internal SDK? google has an SDK for this but it had some properties I didn't really like so I just did it manually with a link
  • ensuring that prefs are set correctly (prefs are future-proof so if we want to change the nag structure down the road, like for example re-nagging after some amount of time, we have a timestamp saved -- though there are no plans for this at the moment)
  • actually verifying that it works on iOS

assigning this to you @jafayer but up to you whether you want to take this on. for motivation, this is what our Android ratings count did after we added the light nag (which is, like, the most polite nag ever -- only shows up at lesson 10 and never shows up again once dismissed)

motivation from our weekly ratings graph:
image
rating prompt landed in sep 2021. the spike in oct 2020 is just because that's when the app really took off

Extend the "loading" animation in the listen screen

In between the track loading and the track auto-playing on the listen screen, there's a period where the "play" button shows. This isn't ideal, since we're about to auto-play the track anyway (it also just kind of looks bad to have all that 'flickering'). We should figure out when we're truly waiting for the user to press the play button (in which case we should render a play button) versus when we're waiting on the track to autoplay (in which case we should keep showing the ActivityIndicator).

Re-populate the queue when downloads finish

If the user begins downloading a bunch of tracks, then starts listening to the course before these downloads finish, the tracks will stream from the server even once the course audio is downloaded to the phone.

This can be kinda crappy if the user has "download only on wi-fi" set, starts a bunch of downloads, starts listening to the course, and then leaves their home once a bunch of tracks have downloaded. It's a safe assumption that the downloaded audio will be used, but in fact the audio will still stream from the server.

This is because we don't update existing tracks in the queue when a download completes. The queue is wiped whenever the user presses the stop button, navigates to a different screen in the app, or kills the app, but listening straight through will prevent the queue from being updated.

A fix for this would observe download-finish events and splice the lesson from the queue (assuming it's in there), replacing it with a track object that has the local URL.

The same issue applies to deleted downloads in the queue.

Ensure assets are appropriately licensed

We need to make sure assets have licenses and that their licenses are clear. This will let us publish to F-Droid.

Assets in question:

  • Course audio
  • Course album art
  • Arabic vocabulary cards (depends on #9)
  • Icons (from two sets)

The application malfunction using RTL

When the application is installed on RTL devices it behaves in undesirable ways: general design looks crooked, the ListenScrubber fails while being moved, and maybe other things I haven't seen.
Because the classes are currently in the English language, the users of the app either way are committed to this language, and therefore also to LTR. That's why I suggest simply canceling the RTL option, at least as a temporary solution.
Maybe just stick some ReactNative.I18nManager.allowRTL(false); in there.

Refactor StatusBar and changeNavigationBarColor calls

These functions get called all over the place, whenever a new screen loads, and it's not DRY.

We can:

  • extract these calls into their own function to keep them DRY
  • OR make this the responsibility of a listener on the navigator

"Mark as unfinished" button for finished lessons

Currently the only way to mark a lesson as unfinished is to delete all course progress. That seems silly.

Where there's currently a "Mark as finished" button (in the bottom sheet), we should have a "Mark as unfinished" button if the track is already marked as finished.

Show course progress on the "all languages" screen

We can load current course progress on the main screen and render language buttons with this progress. Instead of showing "90 lessons", the button might show "Lesson 12 of 90".

Considerations:

  • It's not worth counting the total number of finished lessons; just render the number of the lesson that's "next up".
  • This getNextLesson code should be extracted from the LanguageHomeTopButton component so we can reuse it on both screens.

License notices show strangely after switching to R2

Used to be, the "open source licenses" section was a webview that just showed the contents of https://downloads.languagetransfer.org/NOTICE.

It still is, but after switching to Cloudflare R2 (from Linode object storage), the MIME type is application/octet-stream instead of... well, looks like there was no Content-Type header being served by Linode.

Trouble is, on Android at least, this results in the button downloading the NOTICE file instead of displaying it inline. The webview was kind of the easiest hacky solution, but we can do better by actually fetching the contents and rendering them in some UI (maybe one that's smart about not rendering that massive blob of text in one big view -- needs to be efficient to render).

We could just rename the file to NOTICE.txt, but it'd still require an app update so it knows where to look. Hmm, maybe that's what we should do, just update the URL in the app to NOTICE.txt and start uploading to both endpoints instead.

Either way, requires an app update unless I can send a new content type.

I CAN send a new content type! this is why I run everything through a shim server instead of directly to the CDN. I can just special-case the NOTICE file on the server to either send it directly from the shim lambda or to redirect to a NOTICE.txt file from R2!

lol doesn't matter, i CAN set a new content type on R2.

aws s3api put-object --bucket language-transfer --key NOTICE --body NOTICE --content-type text/plain --acl public-read --endpoint-url https://f38435e2c9280c3bd46c1155cd39ba57.r2.cloudflarestorage.com

thanks for being my rubber duck, github text box

Disallow rotation, or at least make sure landscape mode works well

I don't think we can really commit to making sure every screen looks good in landscape mode, especially given that some screens (like the listen screen) have UI elements sized relative to the screen width.

We should figure out how to just disable non-portrait operation entirely.

Add a build flavor that includes donation links

Google Play rejected our app for including a patreon/donate link. If we want to distribute the APK separately, either by ourselves or through another store like F-Droid, we should include those donation links.

Segment and sort the home screen

Likely depends on #5.

The home screen should be segmented by the course the language is taught in. Courses taught in the user's locale should appear first (with English as the default). There's no need for a header on this top section, but subsequent sections (for different 'source' languages) should have a header explaining: "Courses in Spanish". With #2, all of these headers should just appear in the user's locale.

Other sorting (in order of priority, and open to discussion):

  • Sort by progress: in-progress courses, followed by never-started courses, followed by completed courses
  • Sort by recency: the more recently-used courses should show first. Right now I think we can only determine which course is most recently used rather than when each course was last used.
  • Sort by course type: "complete" courses before "intro" courses (with German likely counting as an Intro course for now)
  • Sort by popularity? Is this subjective, or is it based on live metrics? Right now we just use the sort on the LT website.

Change playback speed

This has been requested by at least one user. React Native Track Player seems to support this.

Considerations:

  • Where does the button go?
  • Do we save this setting between tracks? Between different courses?
  • How will this interact with automatic pausing?

Download to external storage

Hello and thanks for your app.

If it possible please add these features:

  1. Dark mode.
  2. Download on external storage.
  3. When I back from lesson to main page, the lesson stops! But I want it continue (I don't know is it bug or not but it's annoying!)

Delete orphaned downloads in data management

I think it's possible for incomplete downloads to be orphaned. I'm not sure, since I've never seen it happen, but it may be worth adding a button (or an automatic cleanup) to make sure incomplete downloads can be removed. They can't be deleted normally (except by deleting the entire course folder, not even by deleting all downloads), since their filenames include .download at the end.

Button to toggle Autoplay

As a language learner, I want to be able to listen to one lesson at a time (while not staring at my phone) so that I can reflect on what I've just learned and take the course at my own pace.

OnePlus 5t: font clipping across the app

Reported by a user: on the OnePlus 5t, there's some strange clipping going on, as though every bit of text is just barely too large for the container it's in. A single "wrappable unit" seems to get pushed down out of view, either a full word or (in the case of single-word text objects) a single character.

image

image

image

Listen page progress bar can show text past the bounds of the audio

I noticed while testing the app that the progress bar briefly showed "5:15 / 5:14" on the Listen page.

This could be caused by a few things, but it's probably inconsistent rounding or metadata that's inconsistent with the file (or with the player's perception of the file length).

Ideally, we'd never render an "impossible" time, but we should also account for the possibility that the metadata may truly be wrong. For example, if the downloaded metadata says the track length is 2:00 and the track is truly 10:00, we don't want to show "2:00 / 2:00" for 8 minutes.

Options:

  • Show the time with a ceiling (5:14 / 5:14) for a second or two, then snap back to showing an impossible time (5:17 / 5:14) if the track keeps playing past what the metadata says the length of the track is.
  • When the progress exceeds the length of the track, change the track length display maybe to the current progress, or maybe just a "?:??" as we admit we have no idea how long the track is.

Arabic vocabulary cards

The LT website has vocabulary "thinking" cards for Arabic. We'd like to incorporate these into the app, probably as a new button in the Arabic language home screen.

Considerations:

  • What's the best way to view/use these? How do we inform users about how they should be used?
  • How can we make sure they're accessible?
  • Mihalis is working to get and vet audio from native speakers for these cards. How should we incorporate this audio?
  • Should these stream from the server or come built into the app?
  • There are quite a few of them; should we allow people to "mark progress"?

Android 6.0: no possibility to "download all" lessons like for iOS? The button is missing!

I own phones with both OS, iOS and Android. On iOS there is a button on top of a course "Download all xx lessons" if you didn't download them already. However, this button does NOT show up on Android. I am confused if this is intentional, or just an issue with my device, which is:

LG G4
Android 6.0

I also tried to delete everything (although I did not download anything before) e.g. for the course "Spanish" via "Data management", but that didn't help. For your motivation I rated the iOS app 5 stars ;-)

Other ideas what could go wrong, just thoughts and guesses:

  • the button is there but another UI element is drawn over it?
  • internal variables have a wrong state that it was already downloaded?
  • it's really missing on Android?
  • device specific problem

Suspicious is the still open PR and e.g. this:
https://github.com/language-transfer/lt-app/blob/master/js/components/AllLessons/LessonRow.react.js

        <View style={styles.downloadBox}>
          {ready
            ? renderDownloadProgress(downloaded, downloadState, downloading)
            : null}
        </View>

Screenshot Android 6.0 on LG G4:
image

Lesson Progress Bug

Summary:

Sentence Description: Current lesson finishes and auto progress to next lesson while app in background, when returning app to foreground, old lesson is shown as playing instead of new one. Also, old lesson is not marked as finished.

General conclusion I seem to be able to draw:

  • Lesson not marked as finished when lesson completes while app is in background.

Execution Steps:

  1. App in foreground, play lesson (n).
  2. Turn screen off.
  3. Let playback continue to complete lesson (n) and auto progress to lesson (n+1). Note, feel free to pause and play as much as you like using your headset buttons while this is happening.
  4. Turn screen on and, before unlocking, notice the media playback widget shows you are currently on lesson (n+1), as expected. See picture 1
  5. While playing (because I haven't tested this while paused), unlock screen to return app to foreground and notice that current playback indicates you are still on lesson (n+1) as expected but the colorful full-screen lesson playback screen shows you are on lesson (n) instead. See picture 2
  6. Playing and pausing now, while still on that colorful playback screen, should function normally as if you were on lesson (n+1) instead of what it is showing as lesson (n).
  7. Now go back one page to return to that language's home page and notice that it also shows you are on lesson (n) instead of on lesson (n+1). See picture 3
  8. If you press play again, you will start lesson (n) playback instead of where you left off on lesson (n+1).
  9. At this point you may also notice that lesson (n) is not marked as finished, even though it should be.

Pictures:

Picture 1
pic1

Picture 2
pic2

Picture 3
pic3

Issue Setting up Android Development Environment

Hey, first of all, full disclosure I am not an android dev, so apologies if I'm missing something basic!

I followed along the docs to setup the android development environment here: https://reactnative.dev/docs/environment-setup which had me installing Android SDK 29.0.2.

So far so good...

When attempting to run the project on android via npx react-native run-android I received the error:

image

After looking closer into the node_modules that get installed alongside this app, it seems like quite a few are running on Android SDK 28.0.3.

async-storage
masked-view
react-native-navigation-bar-color
react-native-reanimated
react-native-screens
@react-native-community

Screenshot 2021-05-30 at 11 12 51

It looks like these modules might be causing the build error, but as I'm not an android dev (and don't want to waste my Sunday afternoon lol) I thought I'd raise this in case I'm missing something obviously about setting up the android dev environment.

I guess my real question is, should I be downgrading my Android SDK to version 28.0.3, or is it worth trying to upgrade those modules to 29.0.2 to be consistent with the latest react-native docs?

Add a scrubber to the playback progress bar

Most people who try the app comment on this. We haven't prioritized it, since you shouldn't really have a reason to scrub back and forth in the audio (it's meant to be a very linear listening experience), but it still feels a little uncomfortable to listen to audio without this feature. We've come to expect it, as users.

Manually edit progress

I just accidentally allowed the app to keep playing in the Greek course and progress moved from lesson 33 to 59 while I was busy. The only option available in Data Management

Of course the app was only doing what it was told, However it would be good to have an option to manually edit the course progress, either by setting the current lesson number in Data Management, or by press-and-hold in a list of lessons. Perhaps the first option would be much simpler to implement.

'Contact Us' address bounces

Hello,

I tapped the 'Contact Us' button in the Android app and, after writing an email to the address it supplied, the message bounced. I think the mailbox may no longer be in use.

Add a TouchableNativeFeedback shim

iOS doesn't support TouchableNativeFeedback. If we're going to build this thing on iOS, we'll want to build a component that uses TouchableNativeFeedback on Android and TouchableOpacity (or something) on iOS.

Explicitly pausing or stopping the track should save the current track progress

Right now, track progress is saved every 3 seconds when the app is backgrounded. This means stopping the lesson and then returning to it may result in a short progress loss. It's not a huge deal, and it can actually be kind of nice to get a few extra seconds of context when you come back to the track, but it would be better to implement this context deliberately instead of relying on a 'luck of the draw' based on when the progress was last saved.

An explicit stop or pause request from the notification should save the current progress immediately.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.