Code Monkey home page Code Monkey logo

podverse / podverse-rn Goto Github PK

View Code? Open in Web Editor NEW
210.0 6.0 36.0 123.19 MB

Podverse mobile app written in React Native for iOS, Android, and F-Droid

Home Page: https://podverse.fm/about

License: GNU Affero General Public License v3.0

JavaScript 4.92% Java 2.19% Objective-C 0.57% TypeScript 91.67% Shell 0.26% Ruby 0.19% C 0.01% Starlark 0.03% Kotlin 0.16%
podcast podcasts podcasting podcast-player hacktoberfest agplv3 android ios open-source podcasting20

podverse-rn's Introduction

Company Logo

im1 img2 img3

Podverse

generated with markdown-toc

About

Free and open source podcast manager for Android, iOS, and the web.
Check it out at podverse.fm

Listen to all your podcasts on a single application with Podverse!

Podverse included features:

  • Subscribe to podcasts
  • Auto-download episodes
  • Drag-and-drop queue
  • Sleep timer
  • Light/dark mode

Podverse premium features:

  • Create and share podcast clips
  • Switch devices and play from where you left off
  • Sync your subscriptions across devices
  • Sync your queue across devices
  • Create and share playlists
  • Subscribe to playlists

Features requiring updating our servers require Podverse premium membership.
Sign up and try it gratis for three months 🥳

Find us on on these App Stores and our Website:

Get it on F-Droid Get it on Google Play Get it on AppStore

Licensing

All Podverse software is provided under a libre software licence.

Version support

Officially, Podverse supports the following OS versions:

  • iOS: 14-16
  • Android: 11-13

That said, Podverse might work on earlier versions, but our target for each release is to provide full support for at least those versions.

Getting started

If you are looking to run this app or contribute to Podverse for the first time, please read the sections that are relevant for you in our CONTRIBUTE.md file in the podverse-ops repo. Among other things, that file contains instructions for running a local instance of the Podverse database.

More contributing info

Instruction for contributing to the repo for the Podverse Mobile App.

Additional environment setup and installation for Mac or Windows is found within the contribution page.

Translations on Hosted Weblate

Oversettelsesstatus

Team:

Thank you to our contributors!

FAQ:

Why do some clips start at the wrong time?

Most podcast apps today limit clips to be less than a minute, but Podverse allows creating and sharing clips of any length.
The current approach has the drawback of not supporting clips from podcasts that insert dynamic ads.

Dynamic ads are different advertisements rotated into the same episode, so each listener can hear a different series of advertisements.
Since dynamic ads change the overall length of the episode, timestamps of clips created from that episode may be inaccurate.

Full support for podcasts with dynamic ads is possible, but for fair use/legal reasons permission from each podcaster is needed to do so.

What does the license (AGPLv3) mean?

AGPLv3 is the license of all Podverse software. Anyone can use, inspect, change and share freely, as long as everyone gets to share the software.
This is also known as a "share-alike" or "copyleft" license.

Why is Podverse free as in freedom?

Podverse software lets anyone launch their own podcast app as affordably as possible.
Podcast networks can use the Podverse codebase to create their own app for a tiny fraction of what it costs to hire programmers to build a podcast app from scratch.

This levels the playing field between the corporate world and independent media,
so independent media enjoy the same technological advantages as large corporations.
Copylefted libre software and donations is essential to that mission.

podverse-rn's People

Contributors

agates avatar airon90 avatar antviro avatar bittin avatar cocklemon avatar comradekingu avatar dependabot[bot] avatar eugentoptic44 avatar fnogcps avatar giloliveira avatar infergo avatar jastrom85 avatar jimcdc avatar jonycoo avatar kbondarev avatar kreonjr avatar ksb749 avatar kylefdowney avatar lovegaoshi avatar mitchdowney avatar nathanbnm avatar podverse-dev avatar podverse-ops avatar r1jsheth avatar raj-flyfin avatar santossi avatar softinterlingua avatar stevencrader avatar weblate avatar zeyus 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

podverse-rn's Issues

Automatic Playlist

Maybe you should add an optional function so that you can have new, unwatched videos automatically added to a playlist, then removed when watched.

Or somehow, have an optional “not yet listened to/new” folder, even if it’s only stored locally.

ClipTableViewCell

  • podcast image (hide if not provided)
  • mediaRef title
  • podcast title (hide if not provided)
  • episode pubDate (hide if not provided)
  • episode title (hide if not provided)
  • mediaRef start time / end time
  • button More with callback

PodcastTableViewCell

  • podcast image
  • podcast title
  • last episode published date
  • downloaded episode total
  • auto-download on/off indicator
  • new episode available indicator

Podcast page

NavigationHeader

  • button Back
  • text "Podcast"
  • button Share
    • link (web)/podcast/:id

On Page Load

  • load selected type from key store, or load Downloaded by default

TableHeaderCell

  • podcast image
  • podcast title
  • button Podcast Settings
  • indicator auto-download

TableHeaderRow - Button - Type

  • tap to show action sheet
    • options: Downloaded, All Episodes, Clips, About
      • save selected option to key storage

TableHeaderRow - Button - Sort

  • only shows if All Episodes or Clips is selected
  • tap to show action sheet
    • options: most recent, top past hour, top past week, top past day, top past month, top past year, top all time
      • save selected option to key storage

TableView

  • Downloaded
    • on load:
      • retrieve from storage all episodes from this podcast in most recent order
        • load episodes into EpisodeTableViewCells
        • if no episodes from this podcast are in storage, then show "No episodes downloaded" text with a "Show All Episodes" button
  • All Episodes
    • on load:
      • request /episode?podcastId<id>&page=1&sort=<sort>, use most recent sort by default
        • load response into EpisodeTableViewCells
        • if no episodes in response, then show "No episodes found" text
    • on scroll:
      • when end of list is reached: show loading spinner, request the next page, then append the response to the table
      • if 0 results are in a response after page 1, then show "End of list" text
    • on pull down:
      • reveal filter text input
    • on filter text input:
      • request /episode?podcastId=<id>&searchAllFieldsText=<query>&page=1&sort=<sort>
        • load response into EpisodeTableViewCells
        • if no episode in response, then show "No episodes found" text
  • Clips
    • on load:
      • request /mediaRef?podcastId=<id>&page=1&sort=<sort>, use sort from key store or top past week by default, show loading spinner in table view until complete
        • load response into ClipTableViewCells
        • if no mediaRefs in response, then show "No clips found" text
    • on scroll:
      • when end of list is reached: show loading spinner, request the next page, then append the response to the table
      • if 0 results are in a response after page 1, then show "End of results" text
    • on pull down:
      • reveal filter text input
    • on filter text input:
      • request /mediaRef?podcastId=<id>&searchAllFieldsText=<query>&page=1&sort=<sort>
        • load response into ClipTableViewCells
        • if no mediaRefs in response, then show "No clips found" text
  • About
    • load podcast categories
    • load podcast authors
    • load podcast description

EpisodeTableViewCell

  • tap to segue to Episode page
  • button More
    • tap to open action sheet
      • options: Stream/Play, Download, Queue: Next, Queue: Last, Add to Playlist
  • for downloaded episodes only:
    • swipe left to reveal Delete button
      • tap to delete episode from local data

ClipTableViewCell

  • tap to play mediaRef
  • button More
    • tap to open action sheet
      • options: Stream/Play, Queue: Next, Queue: Last, Add to Playlist

Create local storage models

I think we only need local storage models for data that has any use when offline.

  • Podcast
  • Episode
  • MediaRef
  • User

Podcasts page

NavigationHeader

  • text "Podcasts"

On Page Load

  • load Subscribed by default

RefreshControl

  • pull to refresh current podcast data

TableHeaderRow1 - Button - Type

  • tap to show action sheet
    • options: Subscribed, Category

TableHeaderRow2 - Button - Category Type

  • only shows if TableHeaderRow1 Type Category is selected
  • tap to show wheel selector
    • options: All, [categories]

TableHeaderRow2 - Button - Sort

  • only shows if TableHeaderRow1 Type Category is selected
  • load current option from key store, or load top past week by default
  • tap to show action sheet
    • options: alphabetical, top past hour, top past day, top past week, top past month, top past year, top all-time
      • save selected option to key storage

TableHeaderRow3 - Button - Subcategory Type

  • only shows if a TableHeaderRow2 category is selected
  • tap to show wheel selector
    • options: All, [subcategories]

TableView

  • Subscribed
    • on load:
      • retrieve from storage all podcasts in alphabetical order (by sortableTitle)
        • load podcasts into PodcastTableViewCells
      • request /podcast/metadata?podcastId=<ids>
        • show "updating podcasts" text with loading spinner in right side of TableHeaderRow1 during request
        • update podcast data from response
          • indicate if a podcast's lastEpisodePubDate is newer than in local storage
      • if no podcasts are in storage, then show text "You are not subscribed to any podcasts. Tap the button in the top-left to browse by category, or go to the Find page to search for podcasts by title."
  • Category
    • on load:
      • request /category?topLevelCategories=true, use top past week sort by default, show loading spinner in table view until complete
        • load response into TableHeaderRow2 options
      • request /podcast?page=1&sort=<sort>, use sort from key store or "top past week" by default
        • load response into PodcastTableViewCells
        • if no podcasts in response, then show "No podcasts found" text
    • on scroll:
      • when end of list is reached: show loading spinner, request the next page, then append the response to the table
      • if 0 results are in a response after page 1, then show "End of list" text
    • on TableHeaderRow2 option select:
      • request /category?categoryId=<parent category id>
        • load response into TableHeaderRow3 options
      • request /podcast?categoryId=<parent category id>page=1&sort=<sort>
        • load response into PodcastTableViewCells
        • if no podcasts in response, then show "No podcasts found" text

PodcastTableViewCell

  • tap to load Podcast page
  • for Subscribed podcasts only:
    • swipe left to reveal Unsubscribe button
      • unsubscribe from podcast on server
        • request /podcast/toggle-subscribe/:id with auth
      • delete podcast and all episodes from local data

QA Automation

  • Connect AppCenter builds to BrowerStack automation test

Delete downloaded episodes after finished playing

This may need be handled differently on iOS and Android. I wanted to add this feature in the playerEvents file, but it didn't seem like there was a reliable way to grab the track position and duration I wanted...the event would give me the position/duration of the next track, when we need to check the position/duration of the previous track that just finished playing, to determine if the episode should be deleted...

MediaListTableView

Props

{
  allowFilter?: boolean,
  allowPagination?: boolean,
  endReached?: boolean,
  handleQueryLocalStorage?: function,
  handleQueryRefresh?: function,
  handleQueryRemote?: function,
  isLoading?: boolean,
  isLoadingMore?: boolean,
  noResultsFound?: boolean,
  noResultsText: string = 'No results found',
  tableCells: [PVTableViewCell]
}

Events

  • on load:
    • if handleQueryLocalStorage:
      • call handleQueryLocalStorage()
    • else if handleQueryRemote:
      • call handleQueryRemote()
  • on scroll:
    • on end reached:
      • if allowPagination && !noResultsFound && !endReached && handleQueryRemote:
        • call handleQueryRemote(page + 1)
  • on pull down:
    • if allowFilterQuery:
      • first pull:
        • reveal FilterTextInput
      • second pull:
        • reveal RefreshControl
        • call handleQueryRefresh()
    • else:
      • first pull:
        • reveal RefreshControl
        • call handleQueryRefresh()
  • on FilterTextInput text input:
    • call handleQueryRemote(1, <text input>)

Render

<TableView>
  {
    isLoading &&
      <LoadingSpinner />
  }
  {
    !isLoading && tableCells > 0 &&
      {tableCells}
  }
  {
    !isLoading && endReached &&
      <TableCellEndReached />
  }
  {
    !isLoading && isLoadingMore && !endReached &&
      <BottomCellLoadingSpinner />
  }
</TableView>

EpisodeTableViewCell

  • podcast image (hide if not provided)
  • episode title
  • podcast title (hide if not provided)
  • episode pubDate
  • episode duration
  • episode description
  • button More with callback

Episode page

NavigationHeader

  • button Back
  • text "Episode"
  • button Share
    • link (web)/episode/:id

On Page Load

  • load selected type from key store, or load Show Notes by default
  • load selected sort from key store, or load top past week by default
  • request /episode/:id, load response in TableHeaderCell, Show Notes

TableHeaderCell

  • podcast image
  • episode title
  • button More
    • tap to open action sheet
      • options: Stream/Play, Download, Queue: Next, Queue: Last, Add to Playlist
  • indicator downloaded

TableHeaderRow - Button - Type

  • tap to open action sheet
    • options: Show Notes, Clips
      • save selected option to key storage

TableHeaderRow - Button - Sort

  • only shows if Clips is selected
  • tap to open action sheet
    • options: most recent, top past hour, top past week, top past day, top past month, top past year, top all time
      • save selected option to key storage

View

  • Show Notes
    • episode description
      • make links clickable
      • make timestamps playable

TableView

  • Clips
    • on load:
      • request /mediaRef/episodeId=<id>&page=<int>&sort=<sort>
        • load response in ClipTableViewCells
        • if no mediaRefs in response, then show "No clips found" text
    • on scroll:
      • when end of list is reached, show loading spinner, request the next page, then append the response to the table
      • if 0 results are in a response after page 1, then show "End of List" text
    • on pull down:
      • reveal filter text input
    • on filter text input:
      • request /mediaRef?episodeId=<id>&searchAllFieldsText=<query>&page=1&sort=<sort>
        • load response into ClipTableViewCells
        • if no mediaRefs in response, then show "No clips found" text

ClipTableViewCell

  • tap to stream or play mediaRef
  • button More
    • tap to open action sheet
      • options: Stream/Play, Queue: Next, Queue: Last, Add to Playlist

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.