first commit
@@ -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
|
||||
@@ -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 :)
|
||||
@@ -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!
|
||||
@@ -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
|
||||
-->
|
||||
@@ -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
|
||||
@@ -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/
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[submodule ".flutter"]
|
||||
path = .flutter
|
||||
url = https://github.com/flutter/flutter.git
|
||||
branch = stable
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||

|
||||
|
||||
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).
|
||||
@@ -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).
|
||||
|
After Width: | Height: | Size: 214 KiB |
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,175 @@
|
||||

|
||||
|
||||
## 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/>
|
||||
|
After Width: | Height: | Size: 2.5 MiB |
@@ -0,0 +1 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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() {
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
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>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -0,0 +1 @@
|
||||
include ':app'
|
||||
@@ -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="<Group>">
|
||||
<g id="_Group_2" data-name="<Group>">
|
||||
<g id="_Group_3" data-name="<Group>">
|
||||
<path id="_Path_" data-name="<Path>" 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="<Path>" 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="<Group>">
|
||||
<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 |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 4.2 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
@@ -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 |
@@ -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 |
|
After Width: | Height: | Size: 244 KiB |
@@ -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/
|
||||
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
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"
|
||||
@@ -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}
|
||||