PM has a different method to handle API keys compared to other services
which takes the value as an authorization header.
Signed-off-by: kingbri <bdashore3@proton.me>
Debrid services can change their APIs at any time which negatively
impacts user experiences on Ferrite.
Add the following:
- Ability for a user to add a manually generated API key only showing the
last 4 characters for security purposes.
- Make ephemeral auth sessions toggle-able. ASWebAuthenticationView does
not automatically clear on toggle change.
- Add the savedLinks endpoint for AllDebrid so users can access their
downloads and magnets.
- Add a links section to AD's cloud view.
Signed-off-by: kingbri <bdashore3@proton.me>
Some websites and networks may be slow. Add the option to override
the request timeout of 15 seconds for search requests.
Signed-off-by: kingbri <bdashore3@proton.me>
The default SwiftUI picker is too limited for Ferrite's purposes.
Switch to a custom implementation for UI consistency.
Signed-off-by: kingbri <bdashore3@proton.me>
The search bar sometimes had the scope bar added twice if a toolbar
was present (probably caused a refresh of the navigationTitle).
Rather than figuring out a hacky swiftUI solution to solve this,
add a check to enforce only one HostingViewController in the
scope bar.
Also migrate the inlinedList modifier to use safeAreaInsets from
native SwiftUI. Keep the introspected modifier for negative values.
Signed-off-by: kingbri <bdashore3@proton.me>
Filters are more comprehensive and responsive to how many filters
are stored and if a user should clear all of them or not.
Signed-off-by: kingbri <bdashore3@proton.me>
Items can now be filtered based if they're present in the debrid cache,
are a batch file, or not present at all.
Signed-off-by: kingbri <bdashore3@proton.me>
Make searchText a local variable passed to ScrapingModel to prevent
extreme keyboard lag and CPU usage when tracking this EnvironmentObject.
Signed-off-by: kingbri <bdashore3@proton.me>
Make it so that when a user chooses a source to filter, only filter
that specific source when a search occurs.
Also fix the "no results found" overlay text by checking if the
search bar textfield is being edited or not by modifiying ESSearchable.
Signed-off-by: kingbri <bdashore3@proton.me>
ExpandedSearchable opens up the capabilities of the SwiftUI searchable
modifier and allows for additions of more properties such as custom
scope bars.
Since this is a reimplementation of UISearchController, changes
to SwiftUI should not affect search bars that rely on the scope bar
to always be present.
Signed-off-by: kingbri <bdashore3@proton.me>
Place refreshable in the individual lists instead of in the parent
ZStack as that applies to sheets as well.
Signed-off-by: kingbri <bdashore3@proton.me>
These will serve as descriptions for a plugin which will be displayed
in the Plugin Info screen.
website has also replaced baseUrl and dynamicWebsite has replaced
dynamicBaseUrl
Signed-off-by: kingbri <bdashore3@proton.me>
searchURL used to be a required variable in HTML parsers, but some
HTML sources can be single page which means that a search URL isn't
required.
Also make regex matching case insensitive along with adding anchors
to match newlines.
Signed-off-by: kingbri <bdashore3@proton.me>
YAML is a modern configuration format which is human readable
and supports more conventions than JSON.
However, some people may still prefer to write in JSON, so add the
option for users to write legacy JSON if they want to and to provide
backwards compatability with older plugins.
Signed-off-by: kingbri <bdashore3@proton.me>
Make searchbars adhere to autocorrect and fix the random search prompts
not applying by moving functionality to a ViewModel.
Also add a searchbar in the batch choice sheet.
Signed-off-by: kingbri <bdashore3@proton.me>
Titles are now required as an entry without a title shouldn't be
featured. Support via regex is now added for matching along with
splicing strings via capture groups.
If a capture group isn't present, assume that a contains check
is occurring.
Also migrate back to searchText being located in scrapingModel.
Signed-off-by: kingbri <bdashore3@proton.me>
NavigationStack has some glaring UI bugs, so switch back to
NavigationView for now since none of the new benefits from NavigationStack
are actually being used.
Signed-off-by: kingbri <bdashore3@proton.me>
When installing an action and going back and forth to a different tab,
the app crashes on iOS 14.
Fix this by refreshing the list without worrying about previous
state. This makes Ferrite more efficient in terms of plugin fetching.
Signed-off-by: kingbri <bdashore3@proton.me>
Plugin settings used to only be available for installed sources.
Change this to display info about an installed plugin and add settings
depending on the plugin type.
For example, a source will have additional settings specified by its
own views.
Signed-off-by: kingbri <bdashore3@proton.me>
Switching to a list that changes state on updates caused sheets
to break when animating. Place the list in a container ZStack
that doesn't break sheet presentation.
Also modernize the plugin installation buttons and make the catalog
buttons include the plugin list name which should help prevent
duplication.
Signed-off-by: kingbri <bdashore3@proton.me>
It's more reliable to use the plist which contains the min version
to determine if an update notification should be shown.
Signed-off-by: kingbri <bdashore3@proton.me>
onAppear wasn't being called with the current implementation of the
cloud tab in library. Fix this to listen to the selectedDebridType
variable instead of relying on the onAppear call of a view.y
Also do some further project cleanup and LOC removal
Signed-off-by: kingbri <bdashore3@proton.me>
Fix how default actions are picked and add in default app actions
as options for both debrid and magnet defaults. Kodi shows the
action choice sheet with the DisclosureGroup dropped down.
The new Kodi server framework also wasn't implemented in the Kodi
wrapper. Fix that.
Finally, add some iOS 14 fixes and repair the autocorrect search
setting to actually work.
Signed-off-by: kingbri <bdashore3@proton.me>
Plugin lists are universal across clients and OS-specific cases
should be appropriately handled.
OSes can now be added to the deeplink action case and Ferrite scans
for either iOS-specific or fallthrough actions.
There must be 1 action that corresponds to an OS and/or 1 fallback
case, otherwise the action will not show in the plugins list.
Also remove some extraneous files.
Signed-off-by: kingbri <bdashore3@proton.me>
Multiple servers can be added to Ferrite to playback from any Kodi
server that the user wants. This also adds the ability to have
friendly names which makes it easier to select what server to play on.
Each server shows the user whether it's online or not through Kodi's
JSONRPC ping method.
Signed-off-by: kingbri <bdashore3@proton.me>
Logs can be exported into their own files. I'm still debating on
writing a continuous stream to a logfile that persists on app
crashes.
Also make the show error toasts toggle only apply to generic errors
and not customized error toasts.
Signed-off-by: kingbri <bdashore3@proton.me>
Make all tasks run in parallel to increase responsiveness and efficiency
when fetching new data.
However, parallel tasks means that toast errors are no longer feasible.
Instead, add a logging system which has a more detailed view of
app messages and direct the user there if there is an error.
Signed-off-by: kingbri <bdashore3@proton.me>
For versions that require iOS 15 and up, don't notify previous iOS 14
users about a new update. This requires a minVersion attribute in
the shared Application class.
Signed-off-by: kingbri <bdashore3@proton.me>
iOS 16 has a new search bar placement value which applies the searchbar
in the top-right corner with iPads. Searchable does this automatically,
but SwiftUIx's modifier needs this fix.
Signed-off-by: kingbri <bdashore3@proton.me>
Adds support for playing links on a preset Kodi server. This is
less featured than the Ferrite companion, but should still work
without a problem.
Signed-off-by: kingbri <bdashore3@proton.me>
Plugin entries were not syncing properly inside the plugins view.
Instead of adding events to update filtered lists, make it so that
these filtered lists are updated on state changes.
This is the intended method of reactive programming and removes
complexity from filtering logic.
Signed-off-by: kingbri <bdashore3@proton.me>
Since actions use a new API, update default actions to use the
same API rather than the legacy models. If an action is removed,
a prompt will tell the user to change their default debrid/magnet
action and default to the choice sheet.
Also add extra UI fixes and cleanup.
Signed-off-by: kingbri <bdashore3@proton.me>
iOS 14 requires the scope bar modifier to be on the first subview of
the NavView. This is because a VStack wraps the content.
A bug was that the segmented picker was being overlaid due to the
scope bar modifier having an AppStorage call. The AppStorage call
updated the modifier which for some reason added another HostingView.
I am not sure why this happens, but avoid using AppStorage in the modifier
to make sure this doesn't happen again.
Signed-off-by: kingbri <bdashore3@proton.me>
It's redundant to have the navgiation title of the Search view as
"Search" and the searchbar to have the same title. Make the searchbar
have randomized quotes (from a fixed set) that doesn't repeat cases.
Maybe make this customizable in the future?
Signed-off-by: kingbri <bdashore3@proton.me>
The searchbar had a lot of lag when scrolling down the search
results view. This was due to a shared searchText variable which
updated every time the searchbar text changed and caused UI blocking.
Migrate searchText to a local variable and destroy the child
SearchResultsView as it's not needed at this time (may come back
with v0.7 due to searchable).
Also sources now display results progressively without a ProgressView
blocking when each source loads which allows the user to view media
faster.
Signed-off-by: kingbri <bdashore3@proton.me>
Introspect now properly updates on every view lifecycle change, so
add a check to a reference on the UIHostingController and see if it
has been instantiated already.
Also clean up view struct names to reflect what is a modifier.
Signed-off-by: kingbri <bdashore3@proton.me>
The overall UI of Ferrite has been changed to make animations smoother
and streamline the experiences.
A new search filter interface has been added for all iOS versions,
but iOS 15 and up have smooth UI applied due to bugs with searchbars
in iOS 14 (which shouldn't even have a searchbar in the first place).
Also fix the plugin fetching logic to not listen to a combine publisher
and instead use a notification that is easier to control.
Signed-off-by: kingbri <bdashore3@proton.me>
The subName parameter is for aggregate sources that pull from a
child website. Make it so it's possible to include that child
site in parsers.
Also remove the magnet link/hash requirement since it's filtered out
anyways after results are fetched.
Signed-off-by: kingbri <bdashore3@proton.me>
Only entries from the first plugin list would be shown in plugins.
This was because the availableSources array was set every time a list
was iterated upon.
Signed-off-by: kingbri <bdashore3@proton.me>
onAppear does not fire properly on iOS 14 due to a longstanding
bug in SwiftUI. Add a UIKit onAppear hook for listening to these
events and implement inside the backport namespace.
Signed-off-by: kingbri <bdashore3@proton.me>
Plugins are now a unified format for both sources and actions. Actions
dictate what to do with a link and can now be added through a plugin
JSON file.
Backups have also been versioned to improve performance and add action
support.
Tags are used to give small amounts of information before a user
installs a plugin.
Signed-off-by: kingbri <bdashore3@proton.me>
Adding the ability to send sort descriptors adds more flexibility
for the DynamicFetchRequest backport. Use this to fix bookmarks sorting.
Signed-off-by: kingbri <bdashore3@proton.me>
Add a searchbar to filter through various library entries so it's
easier to find items.
Also add fixes for < iOS 16 devices and fix up searchbar constraints.
Signed-off-by: kingbri <bdashore3@proton.me>
This commit adds support for viewing a user's AllDebrid magnet list.
AllDebrid does not save unlocked links, but they do save which magnets
a user has queried.
Also clean up various functions in DebridManager.
Signed-off-by: kingbri <bdashore3@proton.me>
Error handling can be tedious with debrid because network errors
to ignore are present (such as -999). Create a function to properly
display the errors to the user and log them via print statments.
Signed-off-by: kingbri <bdashore3@proton.me>
This is required for PM's cloud since transfers will also add the
files to a user's cloud rather than just fetching the DDL link.
Signed-off-by: kingbri <bdashore3@proton.me>
Magnets are expressed in two different ways: a hash and a link. Both
of these mean the same thing with a magnet link giving more information
if required.
However, there was a disconnect if a hash was present or a link was
present and required many steps to check which was available. Unify
magnets by creating a parent structure that attempts to extract
the hash or create a link in the event that either parameter isn't
provided.
Replace everything except bookmarks (to prevent CoreData complaints
and unnecessary abstraction) to use the new Magnet system.
Signed-off-by: kingbri <bdashore3@proton.me>
Add the ability to view a user's Premiumize files in Ferrite. Files
can be deleted from a user's account directly in Ferrite's list.
Signed-off-by: kingbri <bdashore3@proton.me>
RealDebrid saves a user's unrestricted links and "torrents" (magnet
links in this case). Add the ability to see and queue a user's RD
library in Ferrite itself.
This required a further abstraction of the debrid manager to allow
for more types other than search results to be passed to various
functions.
Deleting an item from RD's cloud list deletes the item from RD as well.
NOTE: This does not track download progress, but it does show if a
magnet is currently being downloaded or not.
Signed-off-by: kingbri <bdashore3@proton.me>
Transitioning the navigation title to inline while editing search
broke for older OS versions. Make a more bulletproof solution to
inline the navigation title when the user commits a search as that's
a definitive event to listen to.
Signed-off-by: kingbri <bdashore3@proton.me>
NotificationCenter posts to other instances of the same button
caused the existing bookmark reference to be nullified for every other
button.
Add a comparison between object IDs to make sure the correct instances
are being nullified.
Signed-off-by: kingbri <bdashore3@proton.me>
Titles weren't cleared on sheet dismiss which caused conflicts between
batches and single files. Fix this.
Signed-off-by: kingbri <bdashore3@proton.me>
Premiumize has a dynamic upper limit of 107-110 (from testing)
hashes per request. To play it safe, cache requests are split by
100 and executed in parallel as 2 (or more) requests.
Signed-off-by: kingbri <bdashore3@proton.me>
This automatically embeds the commit hash and if the build is an
actions nightly or not which will help with debugging crashes.
Signed-off-by: kingbri <bdashore3@proton.me>
I mistakenly added an and condition which caused all debrid services
to fail unless the user is using Premiumize.
Signed-off-by: kingbri <bdashore3@proton.me>
Premiumize is another debrid provider. Add support in addition
to other debrid services.
Add a unified Magnet type that encloses both the link and hash
when needed for certain services.
A universal ASAuthenticationSession has been added to make implicit
authentication easier for services that support it.
Clean up declarations of certain variables that were mismanaged
during the debrid decentralization process.
Signed-off-by: kingbri <bdashore3@proton.me>
AllDebrid is another debrid provider. Add support to Ferrite in
addition to RealDebrid.
The overall debrid login backend has changed to accomodate for a more
agnostic app structure where more services can be added as needed.
Also add some cosmetic changes to search so filters can be added while
searching for a phrase.
Signed-off-by: kingbri <bdashore3@proton.me>
- Make history buttons have 2 lines of text to give more context.
If a batch is given, the full episode name is shown
- Add a "now playing" section to player choices to show what the user
will play in the event of a misclick
- Make the maximum line limit in search results 4 lines to prevent
long title results from taking up the entire cell
- Fix light theme appearance with library since the picker and list
weren't aligned right
Signed-off-by: kingbri <bdashore3@proton.me>
Backups in Ferrite archive a user's bookmarks, history, source lists,
and source names. Sources are not archived due to the size of the backup
increasing exponentially.
These files use the .feb format to avoid JSON conflicts when opening
the file in Ferrite. The backup file can be renamed to JSON for editing
at any time.
Add the Backport namespace to be used for ported features rather
than making a file for every iOS 14 adaptation.
Move history and bookmark creation to the PersistenceController rather
than individual functions.
Signed-off-by: kingbri <bdashore3@proton.me>
Use strict concurrency checking in Xcode 14 to find misuses with
Swift concurrency.
Cleanup files and rearrange them along with fixing comment headers.
Signed-off-by: kingbri <bdashore3@proton.me>
To declutter a RealDebrid user's library, check if the file and
unrestricted link exist and serve those existing links. Otherwise
perform a download like normal.
Sometimes RealDebrid deletes cached items, but still keeps them on
instant availability. Add a way to tell the user that the item
is downloading along with an option to cancel it.
Also remove unnecessary published variables from viewmodels
Signed-off-by: kingbri <bdashore3@proton.me>
Action history is logged and displayed to the user's library.
These are triggered whenever the magnet choice sheet is displayed.
Also redo alerts and action sheets to avoid deprecation notices
for >iOS 14. These will be removed when iOS 14 support is dropped.
There was also a problem with sheet presentation not working after
a sheet was dismissed. Disable the appropriate view when a sheet
is being presented.
Signed-off-by: kingbri <bdashore3@proton.me>
Bookmarks are added through search results and can be accessed through
the library. These can be moved and deleted within the list.
Add a RealDebrid instant availability cache for bookmark IA status
to not overwhelm the API. Instant availability results are fresh on
every search results since the cache is cleared.
Also don't require a source API object to be present for the API parser
button in source settings. If a JSON parser exists for a source, allow
the option to be presented.
Signed-off-by: kingbri <bdashore3@proton.me>
- Make searching case insensitive
- Fix catalog title not hiding when searching an installed source name
- Cancelling a search doesn't add an installed source to the catalog
- Add dynamic predicate changing for iOS 14 and up instead of restricting
to iOS 15
- Migrate updated source fetching to the source model
- Change how filtering works to adapt with the dynamic predicate
changes
Signed-off-by: kingbri <bdashore3@proton.me>
Co-authored-by: kingbri <bdashore3@proton.me>
- Migrate the empty view to a common view which vertically centers
itself to the screen's bounds
- Don't initialize underlying state variables in init as this is
discouraged behavior. Instead, hook the source list editor to an ID
that refreshes when an existing source list URL has been set
Signed-off-by: kingbri <bdashore3@proton.me>
The inset grouped list style has a top inset that adds extra space
between the navigation bar title and the list rows. Use introspect
to remove this space on UITableView and UICollectionView (for iOS 16).
Sections completely ignore the introspect changes, so add a section
header which removes the list row insets.
Signed-off-by: kingbri <bdashore3@proton.me>