first commit
Build / Build for Android (push) Has been cancelled
Build / Build for iOS (push) Has been cancelled

This commit is contained in:
Zakaria
2026-05-18 14:15:38 -04:00
commit 1563409cb1
382 changed files with 45347 additions and 0 deletions
@@ -0,0 +1,65 @@
---
name: dart-best-practices
description: |-
General best practices for Dart development.
Covers code style, effective Dart, and language features.
license: Apache-2.0
---
# Dart Best Practices
## 1. When to use this skill
Use this skill when:
- Writing or reviewing Dart code.
- Looking for guidance on idiomatic Dart usage.
## 2. Best Practices
### Multi-line Strings
Prefer using multi-line strings (`'''`) over concatenating strings with `+` and
`\n`, especially for large blocks of text like SQL queries, HTML, or
PEM-encoded keys. This improves readability and avoids
`lines_longer_than_80_chars` lint errors by allowing natural line breaks.
**Avoid:**
```dart
final pem = '-----BEGIN RSA PRIVATE KEY-----\n' +
base64Encode(fullBytes) +
'\n-----END RSA PRIVATE KEY-----';
```
**Prefer:**
```dart
final pem = '''
-----BEGIN RSA PRIVATE KEY-----
${base64Encode(fullBytes)}
-----END RSA PRIVATE KEY-----''';
```
### Line Length
Avoid lines longer than 80 characters, even in Markdown files and comments.
This ensures code is readable in split-screen views and on smaller screens
without horizontal scrolling.
**Prefer:**
Target 80 characters for wrapping text. Exceptions are allowed for long URLs
or identifiers that cannot be broken.
## Discovery
### Multi-line Strings
To find candidates for multi-line strings, search for string concatenation
with `+` involving newlines:
- **Regex**: `['"]\s*\+\s*['"]`
- **Regex**: `\+\s*['"].*\\n`
### Line Length
- Rely on the `lines_longer_than_80_chars` lint from the analyzer.
## Related Skills
- **[dart-modern-features]**: For idiomatic
usage of modern Dart features like Pattern Matching (useful for deep JSON
extraction), Records, and Switch Expressions.
[dart-modern-features]: https://github.com/kevmoo/dash_skills/blob/main/.agent/skills/dart-modern-features/SKILL.md
+102
View File
@@ -0,0 +1,102 @@
name: Bug Report
description: Use this template to report bugs, unexpected behavior and accessibility problems.
labels: [bug]
body:
- type: markdown
attributes:
value: |
# Bug Report
Thank you for opening a bug report! Please take the time to properly and thoughtfully fill
out this form to make it easier for us to work with you :)
If you notice you cant fully express your issue in this template, you can always
[open a blank template](https://github.com/flloschy/finamp/issues/new?template=BLANK_ISSUE)
with all the creative freedom you'll need
⚠️ One Info before you start filling everything out. ⚠️
If you are *not* using the Beta/Redesign already please only report **critical / app breaking** issues.
This is because the beta version is likely to already have all the features and bug fixes you might be searching for.
- type: checkboxes
id: updated
attributes:
label: Are you using the newest Version?
description: Did you make sure you are already using the [newest version of Finamp](https://github.com/jmshrv/finamp/releases) and there isn't an issue about this already?
options:
- label: Yes, the issue happens on the newest version
required: true
- label: No, there aren't any open issues about this. I checked!
required: true
- type: checkboxes
id: type
attributes:
label: Type of Report
description: You can select multiple if applicable
options:
- label: The app is unusable
- label: Something isn't quite right
- label: Some functionality isn't accessible to me
- label: Accessibility
- label: None of the above
- type: input
id: version
attributes:
label: The exact version of the app
description: You can find the app version inside the settings screen at the top right (the circle with the i)
placeholder: 0.9.18 (beta)
validations:
required: true
- type: checkboxes
id: affects
attributes:
label: Affected Devices/Platform
options:
- label: Android
- label: Android Auto
- label: iOS
- label: Linux
- label: MacOS (iOS version)
- label: MacOS (native)
- label: Windows
- type: input
id: device
attributes:
label: Device
description: If you think the device you are using is part of the problem please fill give some details here
- type: textarea
id: description
attributes:
label: Description & Steps to Reproduce
description: Please describe what the issue precisely is and if possible how you can reproduce it. Additionally a screen-recoding is always welcome! (for legal reasons preferably without audio)
- type: textarea
id: logs
attributes:
label: Logs
description: |
Please state the approximate/exact time of the issue here
and upload the log file. You may need to put the text file into a
.zip due to file size.
To get the logs Open the side menu, click "Logs", and then use the
*share* button at the top right to get the log file.
You can use the following link to open Finamp's "Logs" screen: [🔗 Logs Screen](https://intradeus.github.io/http-protocol-redirector?r=finamp://internal/logs)
value: |
<details>
<summary>Logs</summary>
PLACE YOUR *FULL* LOGS HERE, or attach them as a file
you may censor any private information (although Finamp tries to remove that automatically), just please don't edit out larger sections.
</details>
validations:
required: true
- type: textarea
id: others
attributes:
label: Additional Information
description: If you want to add something which doesn't fit in the above categories feel free to add this here :)
@@ -0,0 +1,69 @@
name: Feature Request
description: Use this template to suggest new functionality while keeping it reasonable :)
labels: feature
body:
- type: markdown
attributes:
value: |
# Feature Request
Thank you for opening a feature Request! Please take the time to properly and thoughtfully fill
out this form to make it easier for us to work with you :)
If you notice you cant fully express your feature in this template, you can always
[open a blank template](https://github.com/flloschy/finamp/issues/new?template=BLANK_ISSUE)
with all the creative freedom you'll need
⚠️ One more Info before you start filling everything out. ⚠️
If you are *not* using the Beta/Redesign already please do **not** open a feature request. New features
will only be added to the Redesign version of the app
- type: checkboxes
id: updated
attributes:
label: Are you using the newest Version?
description: Did you make sure you are already using the [newest version of Finamp](https://github.com/jmshrv/finamp/releases) and there isn't an feature request about this already?
options:
- label: Yes, the feature is still missing on the newest version
required: true
- label: No, there aren't any open request about this. I checked!
required: true
- type: checkboxes
id: type
attributes:
label: Type of Feature
description: You can select multiple if applicable
options:
- label: Something new
- label: Improvement of a feature
- label: None of the above
- type: textarea
id: description
attributes:
label: Description
description: Please describe in detail what the feature is and how it should act facing the user.
- type: textarea
id: reason
attributes:
label: Reasoning
description: Please describe why you would like to have this feature and why it benefits Finamp as a whole.
- type: textarea
id: implementation
attributes:
label: Implementation Notes
description: |
Please give some technical notes like the logic of this feature (when and what should happen and in which order)
If you have more technical knowledge please try to give more information like
- what needs to be done behind the scenes
- potential problems with existing/missing systems
- Packages that might help (from https://pub.dev)
- Packages that may restrict this feature
- Examples how/which other apps are doing this (including screenshots)
- Jellyfin limitations or API endpoints
- type: textarea
id: others
attributes:
label: Additional Information
description: If you want to add something which doesn't fit in the above categories feel free to add this here :)
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Got an idea? Open a Discussion!
url: https://github.com/jmshrv/finamp/discussions
about: "If you're not yet sure if something is a good feature request, you can use this to discuss it with us!"
- name: Finamp Beta Testers Discord Server
url: https://discord.gg/xh9SZ73jWk
about: We use Discord for more efficient and casual discussion. This is the best place to get answers quickly!
+30
View File
@@ -0,0 +1,30 @@
<!-- Just a reminder that text in these brackets is not visible in the rendered output.
You also do **not** need to use this template. You can remove and modify anything however you like!
Its just a suggestion :)
-->
## Changes
<!-- Please describe what this Pull request adds or changes. Possibly with images -->
## Todo before merging
<!-- Add custom todos if deemed necessary to give others an overview on how far this PR is progressing -->
<!-- Did you add UI text?
No? Just check or remove the box
Yes? Make sure you replace hardcoded strings with translations -->
- [ ] Translations
<!-- Did you add settings to the settings screen?
No? Just check or remove the box
Yes? Make sure they are resettable using the button on the respective page! (see finamp_settings_helper.dart)-->
- [ ] Reset Settings
<!-- Did you run into problems?
No? Just check or remove the box
Yes? Look at the CONTRIBUTING.md, maybe you can add something to help others! -->
- [ ] Extended CONTRIBUTING.md
## Related Issues
<!-- List relevant issues to this PR using a format like this
- closes #xyz
- fixes #abc
- follow up to #pr-name
-->
+32
View File
@@ -0,0 +1,32 @@
name: Build
on:
pull_request:
push:
jobs:
build-android:
name: Build for Android
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
java-version: '17'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- run: flutter build apk --debug
build-ios:
name: Build for iOS
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
architecture: x64
- run: flutter pub get
- run: flutter build ios --release --no-codesign
+116
View File
@@ -0,0 +1,116 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# Visual Studio Code related
.classpath
.project
.settings/
.vscode/
# packages file containing multi-root paths
.packages.generated
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
**/generated_plugin_registrant.dart
.packages
.pub-cache/
.pub/
build/
flutter_*.png
linked_*.ds
unlinked.ds
unlinked_spec.ds
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
*.jks
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/.last_build_id
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/ephemeral
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# macOS
**/macos/Flutter/GeneratedPluginRegistrant.swift
macos/Flutter/ephemeral/flutter_export_environment.sh
macos/Flutter/ephemeral/Flutter-Generated.xcconfig
# Coverage
coverage/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock
# Not-yet supported platforms
windows/
linux/
+4
View File
@@ -0,0 +1,4 @@
[submodule ".flutter"]
path = .flutter
url = https://github.com/flutter/flutter.git
branch = stable
+10
View File
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 916c3ac648aa0498a70f32b5fc4f6c51447628e3
channel: beta
project_type: app
+60
View File
@@ -0,0 +1,60 @@
# Contributing to Finamp
Thanks for your interest in contributing to Finamp! This document goes over how to get started on Finamp development, and other ways to contribute.
## Setting up a Development Environment
Finamp is a fairly standard Flutter app, so all you have to do is [install Flutter](https://docs.flutter.dev/get-started/install). Once Flutter is installed, you should be able to run Finamp on emulators/real devices.
### Android Keys
To build release APKs, you need to set up a signing key for Android. To get that set up, follow [this guide](https://docs.flutter.dev/deployment/android#signing-the-app) from the Flutter documentation. Note that if you have Finamp installed already, your phone may panic because the key is different.
### The Arcane Arts (Code Generation)
![A conversation between me and Chaphasilor. I say "did you try running (the Dart build command)?" They reply "I wasn't aware I need to use the arcane arts for this"](assets/arcane-arts.png)
Because Dart doesn't support macros and stuff, a few dependencies rely on code generation which must be run manually. These dependencies are:
* Hive - the database that Finamp uses for storing all data
* `json_serializable` - For deserialising JSON into classes
* Chopper - For talking to Jellyfin over HTTP
* This layer (`lib/services/jellyfin_api.dart`) is not used by the app directly. The user-facing API is located at `lib/services/jellyfin_api_helper.dart`.
To rebuild these files, run `dart run build_runner build --delete-conflicting-outputs`. This must be done when:
* Modifying a class that is returned by Jellyfin (such as the classes in `lib/models/jellyfin_models.dart`)
* Adding fields to a database class (annotated with `@HiveType`)
If you don't rebuild generated files, you will encounter:
* Settings not persisting
* Hive errors on startup
* Missing data when converting JSON to classes
### Hive
As said earlier, Finamp uses Hive for all data storage needs. If you're doing work that involves data storage, I recommend you read [the Hive docs](https://docs.hivedb.dev/#/). Please ensure that your changes work when upgrading Finamp from the current release to your changes, as not handling upgrades will cause the app to crash. When downgrading, you will have to wipe your app data if any changes were made to Hive.
When creating new types, note that you'll also have to register an adapter in `main.dart`. After code generation, there should be a class called `[YourType]Adapter`, which you can initialise in `setupHive`.
## The Redesign
The biggest main piece of work being done on Finamp at the moment is the redesign. The relevant issue can be found [here](https://github.com/jmshrv/finamp/issues/220). The `redesign` branch has diverged a lot from `main`, but I try to keep it updated. If you're struggling to decide what to work on, the redesign is a good place to look :)
## Designing
As the name implies, we'll need many fresh design mockups for the redesign. Some are already done, some are still being interated on, and some mockups haven't been started yet.
If you are a designer or have ideas on how the new user interface could/should look, then it would be amazing and really helpfull if you would create a mockup!
You can share your mockups in an issue here on GitHub (use a relevant one if possible, otherwise create a new one) or on Discord for further discussion.
Once the mockup is finalized, people can start implementing it.
There's also a Figma file with some existing mockups that you can go off of: <https://www.figma.com/design/wVizekpm9YchvHFP6l508r/Finamp?node-id=101-425&t=27CRT9QAwFhlIMqm-1>
Some of the designs in there are already outdated or still a work in progress. When in doubt, you should look at the current design in the actual app, or ask us about it!
## Translating
Finamp uses Weblate to manage translations: **https://hosted.weblate.org/engage/finamp/**
Feel free to add new languages if yours isn't there yet. If you have any questions, such as the context of a string, you can ask in the [Translation Discussions](https://github.com/jmshrv/finamp/discussions/categories/translations).
+37
View File
@@ -0,0 +1,37 @@
# Finamp 1.0 Plan - Downloads Rewrite
## Introduction
This document outlines the core plan and motivation for Finamp 1.0. This change will need a major version bump as it will introduce breaking changes. As such, we will have to ensure that users are notified well in advance.
## Motivations
Finamp's downloading infrastructure is currently very poor. It was mostly written before I had any formal computer science experience. Because of this, it is very finnicky, and frequently breaks between updates. Some highlights include:
* Download items being tracked across five key-value databases that all need to be kept in sync:
* `DownloadedItems` - stores downloaded song data.
* `DownloadedParents` - stores data about parents (albums, playlists), with links to children.
* By link, I mean a copy of the Jellyfin metadata stored in `DownloadedItems`. Syncing between the two is done manually.
* `DownloadIds` - a copy of the data stored in `DownloadedItems`, but indexed by the `flutter_downloader` download ID so that we can track the download ID back to the actual song.
* `DownloadedImages` - stores downloaded image data.
* `DownloadedImageIds` - same as `DownloadIds`, but for images.
* `DownloadIds` cannot be used for images, as it takes a `DownloadedSong` data type (yes, a complete copy).
* In the past, I stored absolute paths. The `DownloadedSong` data-type has to account for this, and update as it goes along.
* This is especially problematic on iOS, where the internal app directory changes every update.
* Off the top of my head, there is no clean way to add support for downloaded artists, or especially genres
The download system also makes use of the [flutter_downloader](https://pub.dev/packages/flutter_downloader) package. In the new system, I will be replacing it with [background_downloader](https://pub.dev/packages/background_downloader) for the following reasons:
* Desktop support - While downloading isn't 100% essential for desktop, it will be nice to have a complete version of Finamp on desktop. Desktop support will also be required for Linux phones.
* Better looking API - `flutter_downloader` is extremely finnicky, especially around listening for updates. This is why download indicators have never really worked in Finamp.
* Scoped storage support - Finamp's support for external directories is currently practically broken. It seems to be a pretty niche feature, but it would be nice to have working again.
* Relative path handling by default - this will solve the absolute path issue I mentioned earlier.
* Better stability - `flutter_downloader` has had a history of spurious bugs causing crashes and other issues. Most recently, [downloads on iOS failed to get marked as complete](https://github.com/jmshrv/finamp/issues/433), causing downloads to effectively break on iOS. I haven't tried `background_downloader` myself yet, but it has a much more rigid testing setup which should help it catch regressions like this.
Finamp also uses [Hive](https://pub.dev/packages/hive) for all of its databases. Hive is a great database, but it isn't intended for complex use-cases like this. The same people behind Hive have created [Isar](https://pub.dev/packages/isar), which supports more advanced use-cases. I didn't use this initially as it was still in early development during Finamp's initial development, but it is now stable. For downloads, it will allow me to actually model relations in the database to make adding and removing downloads more reliable. I will also likely replace Finamp's other Hive databases with Isar databases.
## Impacts
Doing all of this will be an extremely damaging breaking change. Finamp's last breaking change was [0.5.0](https://github.com/jmshrv/finamp/releases/tag/0.5.0), which required all users to clear their app data (loading databases from before 0.5.0 failed). This was almost acceptable back then - Finamp was still in its early days and hadn't yet been released on the App Store or Play Store (0.5.0 was the first release). Now, Finamp has roughly 25,000 downloads (thank you!). I can't just release an update that breaks everything without giving months of notice, especially since the app will be auto-updated to 1.0.
While the app won't fail to launch like 0.5.0 did, it will effectively log the user out (as the user database will be replaced). Downloads will also be wiped by deleting the internal song directory. Users must be aware that this is happening - one of the first "actions" of this will be to add a visible warning to the app linking here (with a brief explanation at the top).
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

+373
View File
@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
+5
View File
@@ -0,0 +1,5 @@
# Privacy
Apple made me supply some kind of privacy policy URL, so I'm writing this.
Finamp does not collect any data. It only talks to the Jellyfin server you set it up with.
+175
View File
@@ -0,0 +1,175 @@
![Banner](./GitHub_Banner.png)
## Hacktoberfest
Ever thought about contributing to Finamp or Open Source in general?
Now is the time! It's Hacktober afterall!
There are a lot of things **you** can help with with regard to Finamp:
- Design Improvements
- Help us redesign some missing screens! We have some mockups to get you started, just ask around here on GitHub or on our [Discord Server](https://discord.gg/xh9SZ73jWk)!
- Fix visual bugs or improve the UI
- Bug Hunting
- [Fixing bugs](https://github.com/jmshrv/finamp/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug)
- Adding reproduction steps for existing bugs
- Finding bugs
- Translations
- You can look at our [Weblate Project](https://hosted.weblate.org/engage/finamp/) to add missing translations
- You can also add descriptions (i.e., where that string appears in the app) to some older translations strings in [this file](https://github.com/jmshrv/finamp/blob/redesign/lib/l10n/app_en.arb)
- Improving Documentation
- User Documentation (Was there anything you struggled with at first when using Finamp? How did you solve it?)
- Developer Documentation (Was there anything you struggled with when contribution code to Finamp? Add your solution to [CONTRIBUTING.md](https://github.com/jmshrv/finamp/blob/redesign/CONTRIBUTING.md))
- Improving the codebase
- Optimizations (eg. Finamp currently consumes a lot of battery)
- Documentation
- Clean up
- Support
- Help other people on our [Discord Server](https://discord.gg/xh9SZ73jWk)
- Give feedback on [Pull Requests](https://github.com/jmshrv/finamp/pulls)
- Spread the word and get your friends to contribute :D
If you like Finamp but don't want to contribute for any reason, you can also contribute [to Jellyfin directly](https://github.com/jellyfin/jellyfin) or to upstream libraries which Finamp uses ([`just_audio`](https://github.com/ryanheise/just_audio), [`background_downloader`](https://github.com/781flyingdutchman/background_downloader/), etc.).
That way you can help Finamp indirectly and Open Source as a whole!
Finamp can't exists without maintained and stable libraries :)
### What to do?
There's still a lot left over from our latest "Finamplify" Hackathon!
Take a look at the [Finamplify Project Board](https://github.com/users/jmshrv/projects/5) or even the full [Redesign Project Board](https://github.com/users/jmshrv/projects/2) (the latter is slightly outdated).
You can find an overview of (hopefully) easy to tackle issues [here on GitHub](https://github.com/jmshrv/finamp/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22easy%20fix%22%20no%3Aassignee). For some of those prior programming experience is definitely helpful.
Specifically, here a short list of long awaited features:
- Car Play
- Metadata editing
- Multi user/server support
- Various improvements for Finamp Desktop (Fixing shuffle, improved UI, better system integration)
- Automatic (Widget) Tests
### How to get started
>[!Important]
> **Make sure to check out the `redesign` branch (`git checkout redesign`)! This is where all development happens at the moment!**
Start by reading the ["Setting up a Development Environment" section](https://github.com/jmshrv/finamp/blob/redesign/CONTRIBUTING.md#setting-up-a-development-environment) in our contribution guidelines.
Then, once flutter is working, you can simply do `flutter run`!
Any changes you do to the code can be applied via hot-reload by pressing `r` in the terminal. There are also first-party Flute integrations for many editors and IDEs.
If you have any questions, just reach out to us on GitHub or [Discord](https://discord.gg/xh9SZ73jWk)!
---
## Redesign Beta
We're currently in the process of redesigning Finamp to transform it into a modern, beautiful, and feature-rich music player made specifically for Jellyfin.
You can join the beta on [Google Play](https://play.google.com/store/apps/details?id=com.unicornsonlsd.finamp) and [Apple TestFlight](https://testflight.apple.com/join/UqHTQTSs), or download the latest beta APK from the [releases page](https://github.com/jmshrv/finamp/releases).
Please note that the beta is still work-in-progress, so the UI and functionality might be inconsistent or incomplete, and is not final. However, the beta is **fully functional and should be stable** enough for daily use.
---
**Finamp** is a Jellyfin music player for Android and iOS. It's meant to give you a similar listening experience as traditional streaming services such as Spotify and Apple Music, but for the music that you already own. It's free, open-source software, just like Jellyfin itself.
Some of its features include:
- A welcoming user interface that looks modern & unique, but still familiar
- Downloading files for offline listening and saving mobile data. Can use transcoded downloads to save even more space.
- Transcoded streaming for saving mobile data
- Beautiful dynamic colors that adapt to your media
- Audio volume normalization ("ReplayGain") (Jellyfin 10.9+)
- Lyrics (Jellyfin 10.9+)
- Gapless playback
- Android Auto support (coming soon™)
- Full support for Jellyfin's "Playback Reporting" feature and plugin, letting you keep track of your listening activity
- Integration with [AudioMuse](https://github.com/NeptuneHub/AudioMuse-AI) for sonic analysis and improved mixes
***You need your own Jellyfin server to use Finamp. If you don't have one yet, take a look at [Jellyfin's website](https://jellyfin.org/) to learn more about it and how to set it up.***
## Getting Finamp
<div style="display: flex; align-items: center;" align="center">
[<img src="app-store-badges/fdroid.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/com.unicornsonlsd.finamp/)
[<img src="app-store-badges/play-store.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=com.unicornsonlsd.finamp)
[<img style="margin-left: 15px;" src="app-store-badges/app-store.svg"
alt="Download on the App Store"
height="55">](https://apps.apple.com/us/app/finamp/id1574922594)
</div>
<sup>Note: The F-Droid release may take a day or two to get updates because [F-Droid only builds once a day](https://www.f-droid.org/en/docs/FAQ_-_App_Developers/#ive-published-a-new-release-why-is-it-not-in-the-repository).</sup>
The app is also available as an APK from the [releases page](https://github.com/jmshrv/finamp/releases).
The SHA-256 fingerprint of Finamp's signing certificate is `20:61:C5:C9:28:9C:00:02:08:81:B7:E5:33:4D:93:A0:2D:FA:4B:E9:80:AF:20:C0:5D:B4:E5:29:C8:DA:5B:54`. Google Play releases and provided APKs will be signed with this certificate. F-Droid releases will be signed with F-Droid's own signing certificates.
### Frequently Asked Questions
#### Before Installing
##### Is Finamp free?
Absolutely! It costs nothing to use. We do appreciate voluntary contributions of any kind though, be that bug reports, code, designs, or ideas for new features. You can also donate to some of the developers to show your appreciation <3
##### How can I install Finamp?
On Android, Finamp can be installed from the Google Play Store, F-Droid store, or directly by installing the APK file from GitHub.
On iOS, you can install Finamp through Apple's App Store. Just click on the buttons above.
##### Does Finamp support my media formats?
Finamp should support all formats supported by Jellyfin. Some more advanced formats could cause issues for regular playback, but transcoding should fix these issues.
##### Does Finamp support Android Auto / Apple CarPlay?
Theoretically, but not yet. There is [an issue for this](https://github.com/jmshrv/finamp/issues/24) that contains a proof of concept for Android Auto in there, but it hasn't been tested yet. Maybe you could help out!
##### Is Finamp legal?
Yes. Finamp is a *tool* that lets you interface with a Jellyfin server. Finamp does not come with any music, and will not connect to streaming services other than Jellyfin. You will need to bring your own media and add it to Jellyfin, for example by purchasing music online. This often also directly supports your favorite artists!
#### After Installing
##### I'm having trouble with Finamp, where can I find help?
If you're experiencing software bugs or other issues with Finamp, be sure to take a look at [Finamp's issue tracker](https://github.com/jmshrv/finamp/issues), especially the pinned issues at the top of the page. If you can't find anything related to your specific problem, please create a new issue (you will need a GitHub account).
## Contributing
Finamp is a community-driven project and relies on people like **you** and their contributions. To learn how you could help out with making Finamp even better, take a look at our [Contribution Guidelines](CONTRIBUTING.md)
### Translations
You can also contribute by helping to translate Finamp! This is done through our Weblate instance here: <https://hosted.weblate.org/engage/finamp/>. The current translation status is this:
<a href="https://hosted.weblate.org/engage/finamp/">
<img src="https://hosted.weblate.org/widget/finamp/finamp/horizontal-auto.svg" alt="Translation status" />
</a>
## Known Issues
This app is still a work in progress, and has some bugs/issues that haven't been fixed yet. Here is a list of currently known issues:
- Reordering the queue while shuffle is enabled is not possible at the moment. It seems like this is an issue with a dependency of Finamp (`just_audio`), and is being tracked [here](https://github.com/ryanheise/just_audio/issues/1042)
- If you have a very large library or an older phone, performance might not be great in some places
## Planned Features
- Improved Android Auto / Apple CarPlay support
- Full redesign, adding more features and a home screen. See [this issue](https://github.com/jmshrv/finamp/issues/220) for more info
- Better playlist editing
- Multiple users/servers
- More customization options
## Screenshots (Stable Version, outdated)
| | |
|:-------------------------:|:-------------------------:|
|<img src=<https://raw.githubusercontent.com/jmshrv/finamp/master/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png>> | <img src=<https://raw.githubusercontent.com/jmshrv/finamp/master/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png>>
| <img src=<https://raw.githubusercontent.com/jmshrv/finamp/master/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png>> | <img src=<https://raw.githubusercontent.com/jmshrv/finamp/master/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png>> |
Name source: <https://www.reddit.com/r/jellyfin/comments/hjxshn/jellyamp_crossplatform_desktop_music_player/fwqs5i0/>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

+1
View File
@@ -0,0 +1 @@
include: package:flutter_lints/flutter.yaml
+14
View File
@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/
# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
+77
View File
@@ -0,0 +1,77 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 34
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
applicationId "com.unicornsonlsd.finamp"
minSdkVersion 21
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
// shrinkResources false
// minifyEnabled false
}
debug {
applicationIdSuffix '.debug'
minifyEnabled true // avoid dexing issues
}
}
}
flutter {
source '../..'
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.mediarouter:mediarouter:1.7.0'
}
@@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unicornsonlsd.finamp">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
+53
View File
@@ -0,0 +1,53 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unicornsonlsd.finamp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application android:name="${applicationName}" android:label="Finamp" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:requestLegacyExternalStorage="true" android:allowBackup="false" android:fullBackupContent="false">
<activity android:name="com.ryanheise.audioservice.AudioServiceActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:exported="true">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.APP_MUSIC"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name="com.ryanheise.audioservice.AudioService" android:foregroundServiceType="mediaPlayback" android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" android:exported="true"/>
</intent-filter>
</receiver>
<receiver
android:name="androidx.mediarouter.media.MediaTransferReceiver"
android:exported="true">
</receiver>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data android:name="flutterEmbedding" android:value="2" />
</application>
</manifest>
@@ -0,0 +1,6 @@
package com.unicornsonlsd.finamp
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/black" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

+3
View File
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/*" />
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#000B25</color>
</resources>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:navigationBarColor">@android:color/black</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
<item name="android:navigationBarColor">@android:color/black</item>
</style>
</resources>
@@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unicornsonlsd.finamp">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
+29
View File
@@ -0,0 +1,29 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
afterEvaluate { project ->
if (project.plugins.hasPlugin("com.android.application") ||
project.plugins.hasPlugin("com.android.library")) {
project.android {
compileSdkVersion 34
buildToolsVersion "34.0.0"
}
}
}
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
+4
View File
@@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
+26
View File
@@ -0,0 +1,26 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
}
include ":app"
+1
View File
@@ -0,0 +1 @@
include ':app'
+46
View File
@@ -0,0 +1,46 @@
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
<title>Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917</title>
<g>
<g>
<g>
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" style="fill: #a6a6a6"/>
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"/>
</g>
<g id="_Group_" data-name="&lt;Group&gt;">
<g id="_Group_2" data-name="&lt;Group&gt;">
<g id="_Group_3" data-name="&lt;Group&gt;">
<path id="_Path_" data-name="&lt;Path&gt;" d="M24.76888,20.30068a4.94881,4.94881,0,0,1,2.35656-4.15206,5.06566,5.06566,0,0,0-3.99116-2.15768c-1.67924-.17626-3.30719,1.00483-4.1629,1.00483-.87227,0-2.18977-.98733-3.6085-.95814a5.31529,5.31529,0,0,0-4.47292,2.72787c-1.934,3.34842-.49141,8.26947,1.3612,10.97608.9269,1.32535,2.01018,2.8058,3.42763,2.7533,1.38706-.05753,1.9051-.88448,3.5794-.88448,1.65876,0,2.14479.88448,3.591.8511,1.48838-.02416,2.42613-1.33124,3.32051-2.66914a10.962,10.962,0,0,0,1.51842-3.09251A4.78205,4.78205,0,0,1,24.76888,20.30068Z" style="fill: #fff"/>
<path id="_Path_2" data-name="&lt;Path&gt;" d="M22.03725,12.21089a4.87248,4.87248,0,0,0,1.11452-3.49062,4.95746,4.95746,0,0,0-3.20758,1.65961,4.63634,4.63634,0,0,0-1.14371,3.36139A4.09905,4.09905,0,0,0,22.03725,12.21089Z" style="fill: #fff"/>
</g>
</g>
<g>
<path d="M42.30227,27.13965h-4.7334l-1.13672,3.35645H34.42727l4.4834-12.418h2.083l4.4834,12.418H43.438ZM38.0591,25.59082h3.752l-1.84961-5.44727h-.05176Z" style="fill: #fff"/>
<path d="M55.15969,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H48.4302v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.645,21.34766,55.15969,23.16406,55.15969,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30227,29.01563,53.24953,27.81934,53.24953,25.96973Z" style="fill: #fff"/>
<path d="M65.12453,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H58.395v1.50586h.03418A3.21162,3.21162,0,0,1,61.312,21.34766C63.60988,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26711,29.01563,63.21438,27.81934,63.21438,25.96973Z" style="fill: #fff"/>
<path d="M71.71047,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51855-3.61426,2.624,0,4.42285,1.47168,4.4834,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60645,1.626,3.60645,3.44238,0,2.32324-1.85059,3.77832-4.79395,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" style="fill: #fff"/>
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" style="fill: #fff"/>
<path d="M86.065,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72609,30.6084,86.065,28.82617,86.065,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40039,1.16211-2.40039,3.10742c0,1.96191.89453,3.10645,2.40039,3.10645S92.76027,27.93164,92.76027,25.96973Z" style="fill: #fff"/>
<path d="M96.18606,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" style="fill: #fff"/>
<path d="M109.3843,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10207,25.13477Z" style="fill: #fff"/>
</g>
</g>
</g>
<g id="_Group_4" data-name="&lt;Group&gt;">
<g>
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" style="fill: #fff"/>
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" style="fill: #fff"/>
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" style="fill: #fff"/>
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z" style="fill: #fff"/>
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" style="fill: #fff"/>
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" style="fill: #fff"/>
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" style="fill: #fff"/>
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" style="fill: #fff"/>
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" style="fill: #fff"/>
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" style="fill: #fff"/>
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" style="fill: #fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

+121
View File
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="finampLogo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.5499273"
inkscape:cx="113.65139"
inkscape:cy="371.86734"
inkscape:window-width="2560"
inkscape:window-height="1387"
inkscape:window-x="1912"
inkscape:window-y="22"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient19145">
<stop
style="stop-color:#ac5fc8;stop-opacity:1;"
offset="0"
id="stop19141" />
<stop
style="stop-color:#ac5fc8;stop-opacity:0;"
offset="1"
id="stop19143" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient13668">
<stop
style="stop-color:#03a2db;stop-opacity:1;"
offset="0"
id="stop13664" />
<stop
style="stop-color:#03a2db;stop-opacity:0;"
offset="1"
id="stop13666" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient13668"
id="linearGradient13670"
x1="56.772655"
y1="173.68584"
x2="14.91485"
y2="176.33202"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.7448971,0,0,2.7448971,13.238109,-340.26991)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19145"
id="linearGradient19147"
x1="156.90707"
y1="171.53432"
x2="141.45052"
y2="174.40752"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-69.983312,2.64853)" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g19295"
transform="matrix(2.7448971,0,0,2.7448971,-85.149304,-350.17468)"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113">
<path
style="fill:#8374d3;fill-opacity:0.976471;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.761869,1.78495 -0.782803,4.12998 -6.976413,10.59124 -6.639161,6.92604 -8.498864,8.13677 -11.243381,7.31984 -2.744517,-0.81694 -3.63939,-2.84759 -5.410216,-12.27694 -2.70079,-14.38134 -1.782587,-15.19973 12.337815,-10.99665 7.155122,2.12977 10.613347,3.77205 11.292195,5.36251 z"
id="path357"
sodipodi:nodetypes="ssssss" />
<path
style="fill:url(#linearGradient19147);fill-opacity:1;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.76187,1.78495 -0.7828,4.12998 -6.97641,10.59124 -6.63916,6.92604 -8.49886,8.13677 -11.24338,7.31984 -2.74452,-0.81694 -3.63939,-2.84759 -5.41022,-12.27694 -2.70079,-14.38134 -1.78258,-15.19973 12.33782,-10.99665 7.15512,2.12977 10.61334,3.77205 11.29219,5.36251 z"
id="path357-3"
sodipodi:nodetypes="ssssss" />
</g>
<path
style="fill:#4f87d3;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
<path
style="fill:url(#linearGradient13670);fill-opacity:1;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129-6"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

+126
View File
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="174.49809mm"
height="214.19034mm"
viewBox="0 0 174.49809 214.19034"
version="1.1"
id="svg5"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
sodipodi:docname="icon_foreground_noborder.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.5499273"
inkscape:cx="-546.43587"
inkscape:cy="237.30409"
inkscape:window-width="2560"
inkscape:window-height="1379"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient19145">
<stop
style="stop-color:#ac5fc8;stop-opacity:1;"
offset="0"
id="stop19141" />
<stop
style="stop-color:#ac5fc8;stop-opacity:0;"
offset="1"
id="stop19143" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient13668">
<stop
style="stop-color:#03a2db;stop-opacity:1;"
offset="0"
id="stop13664" />
<stop
style="stop-color:#03a2db;stop-opacity:0;"
offset="1"
id="stop13666" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient13668"
id="linearGradient13670"
x1="56.772655"
y1="173.68584"
x2="14.91485"
y2="176.33202"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.7448971,0,0,2.7448971,13.238109,-340.26991)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19145"
id="linearGradient19147"
x1="156.90707"
y1="171.53432"
x2="141.45052"
y2="174.40752"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-69.983312,2.64853)" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-20.038498,-35.690324)">
<g
id="g19295"
transform="matrix(2.7448971,0,0,2.7448971,-85.149304,-350.17468)"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113">
<path
style="fill:#8374d3;fill-opacity:0.976471;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.761869,1.78495 -0.782803,4.12998 -6.976413,10.59124 -6.639161,6.92604 -8.498864,8.13677 -11.243381,7.31984 -2.744517,-0.81694 -3.63939,-2.84759 -5.410216,-12.27694 -2.70079,-14.38134 -1.782587,-15.19973 12.337815,-10.99665 7.155122,2.12977 10.613347,3.77205 11.292195,5.36251 z"
id="path357"
sodipodi:nodetypes="ssssss" />
<path
style="fill:url(#linearGradient19147);fill-opacity:1;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.76187,1.78495 -0.7828,4.12998 -6.97641,10.59124 -6.63916,6.92604 -8.49886,8.13677 -11.24338,7.31984 -2.74452,-0.81694 -3.63939,-2.84759 -5.41022,-12.27694 -2.70079,-14.38134 -1.78258,-15.19973 12.33782,-10.99665 7.15512,2.12977 10.61334,3.77205 11.29219,5.36251 z"
id="path357-3"
sodipodi:nodetypes="ssssss" />
</g>
<path
style="fill:#4f87d3;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
<path
style="fill:url(#linearGradient13670);fill-opacity:1;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129-6"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

+81
View File
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="174.49809mm"
height="214.19034mm"
viewBox="0 0 174.49809 214.19034"
version="1.1"
id="svg5"
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
sodipodi:docname="icon_white.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.5499273"
inkscape:cx="37.277655"
inkscape:cy="237.30409"
inkscape:window-width="2560"
inkscape:window-height="1379"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-20.038498,-35.690324)">
<g
id="g19295"
transform="matrix(2.7448971,0,0,2.7448971,-85.149304,-350.17468)"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113"
style="fill:#ffffff">
<path
style="fill:#ffffff;fill-opacity:0.976471;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.761869,1.78495 -0.782803,4.12998 -6.976413,10.59124 -6.639161,6.92604 -8.498864,8.13677 -11.243381,7.31984 -2.744517,-0.81694 -3.63939,-2.84759 -5.410216,-12.27694 -2.70079,-14.38134 -1.782587,-15.19973 12.337815,-10.99665 7.155122,2.12977 10.613347,3.77205 11.292195,5.36251 z"
id="path357"
sodipodi:nodetypes="ssssss" />
<path
style="fill:#ffffff;fill-opacity:1;stroke-width:1.38759"
d="m 86.923758,174.18284 c 0.76187,1.78495 -0.7828,4.12998 -6.97641,10.59124 -6.63916,6.92604 -8.49886,8.13677 -11.24338,7.31984 -2.74452,-0.81694 -3.63939,-2.84759 -5.41022,-12.27694 -2.70079,-14.38134 -1.78258,-15.19973 12.33782,-10.99665 7.15512,2.12977 10.61334,3.77205 11.29219,5.36251 z"
id="path357-3"
sodipodi:nodetypes="ssssss" />
</g>
<path
style="fill:#ffffff;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4.05303"
d="M 65.442823,249.88067 C 107.39851,201.4614 -0.8710467,61.238187 108.17921,79.391729 c 13.36958,2.074511 24.80995,3.005251 44.42273,1.055578 27.28719,-16.434166 24.38907,-21.254425 41.93465,-37.841948 -89.53923,1.085524 -55.65997,6.596756 -104.905227,-1.84781 C 73.119683,37.926215 48.768798,31.204868 33.133227,40.254931 16.154493,50.082514 20.097326,80.905705 21.301285,97.192167 24.807548,144.61656 32.518631,213.59609 65.442823,249.88067"
id="path129-6"
sodipodi:nodetypes="cccccccc"
inkscape:export-filename="C:\Users\Sivilian\Pictures\Finamp.png"
inkscape:export-xdpi="113"
inkscape:export-ydpi="113" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

@@ -0,0 +1,3 @@
This release adds a new storage selector and other minor improvements. This new selector can pick the app's external storage directories, which should get around Android permission issues.
Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.4.3
@@ -0,0 +1,3 @@
This release contains many new features, but also breaking changes. You'll have to clear your app data.
Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.5.0
@@ -0,0 +1 @@
Bug fix release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.5.1
@@ -0,0 +1 @@
This release adds way to much to talk about here. Release notes at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.0
@@ -0,0 +1 @@
Bug fix release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.1
@@ -0,0 +1 @@
Bug fix release. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.2
@@ -0,0 +1 @@
Bug fix/a few features release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.3
@@ -0,0 +1 @@
Minor feature release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.4
@@ -0,0 +1 @@
Minor feature release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.5
@@ -0,0 +1 @@
Minor feature release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.6
@@ -0,0 +1 @@
Bug fix release. Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.6.7
@@ -0,0 +1 @@
Bug fix release. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.8
@@ -0,0 +1 @@
(not very) minor feature release. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.9
@@ -0,0 +1 @@
Lots of bug fixes. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.11
@@ -0,0 +1 @@
Fixed issue that broke downloading from HTTP servers
@@ -0,0 +1 @@
Downloader fixes, and a language selector. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.13
@@ -0,0 +1 @@
Downloader fixes, and a language selector. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.14
@@ -0,0 +1 @@
New features and bug fixes. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.15
@@ -0,0 +1 @@
Fixed a bug created in 0.6.15. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.16
@@ -0,0 +1 @@
Fix F-Droid build. Changes from 0.6.16 (which was missed) can be seen at https://github.com/jmshrv/finamp/releases/tag/0.6.16
@@ -0,0 +1 @@
Quality of life and bug fixes. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.18
@@ -0,0 +1 @@
New features and bug fixes. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.20
@@ -0,0 +1 @@
New features and bug fixes. Full changelog at https://github.com/jmshrv/finamp/releases/tag/0.6.21
@@ -0,0 +1 @@
Fixed a bug where the artist screen would show albums from the whole library instead of the specific artist.
@@ -0,0 +1 @@
Fixed a bug where the artist screen would show albums from the whole library instead of the specific artist.
@@ -0,0 +1 @@
Reverted to Android API 33 since 34 seems to break background playback
@@ -0,0 +1 @@
Updated translations, rebuilt with a newer version of Flutter. Changes are now only happening on the redesign beta, check it out on GitHub!
@@ -0,0 +1 @@
Updated dependencies, fixed F-Droid build. Changes are now only happening on the redesign beta, check it out on GitHub!
@@ -0,0 +1 @@
Fixed background playback. Changes are now only happening on the redesign beta, check it out on GitHub!
@@ -0,0 +1 @@
This release just adds required metadata for the F-Droid release.
@@ -0,0 +1,3 @@
This release adds a lot of stuff, but the main thing is that you can now choose where to store downloads. Download locations can be configured in the settings screen. You can pick any directory that your phone would usually have access to, including SD cards. On iOS, you can store files in Files. Deleting songs manually (via your file manager) shouldn't break anything, but I wouldn't recommend it anyway.
Full changelog at https://github.com/UnicornsOnLSD/finamp/releases/tag/0.4.0
@@ -0,0 +1 @@
This release fixes a bug where viewing an artist's albums will show a grey screen if any of the albums didn't have a release year. Artist's albums are now sorted by the server, like with everything else. I've also added some stuff so that unknown years don't show up as "null".
@@ -0,0 +1 @@
This hotfix fixes all album tab views being grey, which was caused by the fix in the last hotfix.
@@ -0,0 +1,22 @@
Finamp is a Jellyfin music player for Android and iOS. Its main feature is the ability to download songs for offline listening.
Translations
Finamp uses Weblate to manage translations: https://hosted.weblate.org/engage/finamp/
Feel free to add new languages if yours isn't there yet. If you have any questions, such as the context of a string, you can ask in the Translation Discussions (https://github.com/jmshrv/finamp/discussions/categories/translations).
Known Issues
This app is still a work in progress, and has some bugs/issues that haven't been fixed yet. Here is a list of currently known issues:
<li>Deleting large items (such as playlists) will cause the app to freeze for a few seconds</li>
<li>Download indicators occasionally don't update</li>
Planned Features
<li>Transcoding support for downloads</li>
<li>Multiple users/servers</li>
<li>Translation support</li>
Name source: https://www.reddit.com/r/jellyfin/comments/hjxshn/jellyamp_crossplatform_desktop_music_player/fwqs5i0/
Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

@@ -0,0 +1 @@
Finamp is a music player for Jellyfin.
@@ -0,0 +1,4 @@
flutter_icons:
android: true
ios: false
image_path: "assets/icon/icon_white_noborder.png"
Executable
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env sh
##############################################################################
##
## Flutter start up script for UN*X
## Version: v1.3.1
## Date: 2023-04-12 16:58:43
##
## Use this flutter wrapper to bundle Flutter within your project to make
## sure everybody builds with the same version.
##
## Read about the install and uninstall process in the README on GitHub
## https://github.com/passsy/flutter_wrapper
##
## Inspired by gradle-wrapper.
##
##############################################################################
echoerr() { echo "$@" 1>&2; }
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ]; do
ls=$(ls -ld "$PRG")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' >/dev/null; then
PRG="$link"
else
PRG=$(dirname "$PRG")"/$link"
fi
done
SAVED="$(pwd)"
cd "$(dirname "$PRG")/" >/dev/null
APP_HOME="$(pwd -P)"
cd "$SAVED" >/dev/null
FLUTTER_SUBMODULE_NAME='.flutter'
GIT_HOME=$(git -C "${APP_HOME}" rev-parse --show-toplevel)
FLUTTER_DIR="${GIT_HOME}/${FLUTTER_SUBMODULE_NAME}"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
# Fix not initialized flutter submodule
if [ ! -f "${FLUTTER_DIR}/bin/flutter" ]; then
echoerr "$FLUTTER_SUBMODULE_NAME submodule not initialized. Initializing..."
git submodule update --init "${FLUTTER_DIR}"
fi
# Detect detach HEAD and fix it. commands like upgrade expect a valid branch, not a detached HEAD
FLUTTER_SYMBOLIC_REF=$(git -C "${FLUTTER_DIR}" symbolic-ref -q HEAD)
if [ -z "${FLUTTER_SYMBOLIC_REF}" ]; then
FLUTTER_REV=$(git -C "${FLUTTER_DIR}" rev-parse HEAD)
FLUTTER_CHANNEL=$(git -C "${GIT_HOME}" config -f .gitmodules submodule.${FLUTTER_SUBMODULE_NAME}.branch)
if [ -z "${FLUTTER_CHANNEL}" ]; then
echoerr "Warning: Submodule '$FLUTTER_SUBMODULE_NAME' doesn't point to an official Flutter channel \
(one of stable|beta|dev|master). './flutterw upgrade' will fail without a channel."
echoerr "Fix this by adding a specific channel with:"
echoerr " - './flutterw channel <channel>' or"
echoerr " - Add 'branch = <channel>' to '$FLUTTER_SUBMODULE_NAME' submodule in .gitmodules"
else
echoerr "Fixing detached HEAD: '$FLUTTER_SUBMODULE_NAME' submodule points to a specific commit $FLUTTER_REV, not channel '$FLUTTER_CHANNEL' (as defined in .gitmodules)."
# Make sure channel is fetched
# Remove old channel branch because it might be moved to an unrelated commit where fast-forward pull isn't possible
git -C "${FLUTTER_DIR}" branch -q -D "${FLUTTER_CHANNEL}" 2> /dev/null || true
git -C "${FLUTTER_DIR}" fetch -q origin
# bind current HEAD to channel defined in .gitmodules
git -C "${FLUTTER_DIR}" checkout -q -b "${FLUTTER_CHANNEL}" "${FLUTTER_REV}"
git -C "${FLUTTER_DIR}" branch -q -u "origin/${FLUTTER_CHANNEL}" "${FLUTTER_CHANNEL}"
echoerr "Fixed! Migrated to channel '$FLUTTER_CHANNEL' while staying at commit $FLUTTER_REV. './flutterw upgrade' now works without problems!"
git -C "${FLUTTER_DIR}" status -bs
fi
fi
# Wrapper tasks done, call flutter binary with all args
set -e
"$FLUTTER_DIR/bin/flutter" "$@"
set +e
# Post flutterw tasks. exit code from /bin/flutterw will be used as final exit
FLUTTER_EXIT_STATUS=$?
if [ ${FLUTTER_EXIT_STATUS} -eq 0 ]; then
# ./flutterw channel CHANNEL
if echo "$@" | grep -q "channel"; then
if [ -n "$2" ]; then
# make sure .gitmodules is updated as well
CHANNEL=${2} # second arg
git config -f "${GIT_HOME}/.gitmodules" "submodule.${FLUTTER_SUBMODULE_NAME}.branch" "${CHANNEL}"
# makes sure nobody forgets to do commit all changed files
git add "${GIT_HOME}/.gitmodules"
git add "${FLUTTER_DIR}"
fi
fi
# ./flutterw upgrade
if echo "$@" | grep -q "upgrade"; then
# makes sure nobody forgets to do commit the changed submodule
git add "${FLUTTER_DIR}"
# flutter packages get runs automatically. Stage those changes as well
if [ -f pubspec.lock ]; then
git add pubspec.lock
fi
fi
fi
exit ${FLUTTER_EXIT_STATUS}

Some files were not shown because too many files have changed in this diff Show More