mirror of
https://github.com/localsend/localsend.git
synced 2026-06-23 04:10:07 +00:00
feat: FOSS version
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
name: Compile APK
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
FLUTTER_VERSION: "3.16.2"
|
||||
APK_BUILD_DIR: "/tmp/build"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
version: ${{ steps.get_version.outputs.version }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get version from pubspec.yaml
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(sed -n 's/^version: \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' app/pubspec.yaml)
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
build_apk:
|
||||
needs: build
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Remove proprietary dependencies
|
||||
run: sh scripts/remove_proprietary_dependencies.sh
|
||||
|
||||
- name: Copy files to env.APK_BUILD_DIR
|
||||
run: |
|
||||
mkdir -p $APK_BUILD_DIR
|
||||
cp -r . $APK_BUILD_DIR
|
||||
|
||||
- name: Decode key.properties file
|
||||
working-directory: ${{ env.APK_BUILD_DIR }}
|
||||
env:
|
||||
ENCODED_STRING: ${{ secrets.ANDROID_KEY_PROPERTIES }}
|
||||
run: echo $ENCODED_STRING | base64 -di > app/android/key.properties
|
||||
|
||||
- name: Decode android-keystore.jks file
|
||||
working-directory: ${{ env.APK_BUILD_DIR }}
|
||||
env:
|
||||
ENCODED_STRING: ${{ secrets.ANDROID_KEY_STORE }}
|
||||
run: mkdir secrets && echo $ENCODED_STRING | base64 -di > secrets/android-keystore.jks
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
|
||||
- name: Install Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Dependencies
|
||||
working-directory: ${{ env.APK_BUILD_DIR }}/app
|
||||
run: flutter pub get
|
||||
|
||||
- name: Build APK
|
||||
working-directory: ${{ env.APK_BUILD_DIR }}/app
|
||||
run: flutter build apk
|
||||
|
||||
- name: Upload APK
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: apk-result
|
||||
path: ${{ env.APK_BUILD_DIR }}/app/build/app/outputs/flutter-apk/app-release.apk
|
||||
@@ -30,6 +30,9 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Remove proprietary dependencies
|
||||
run: sh scripts/remove_proprietary_dependencies.sh
|
||||
|
||||
- name: Copy files to env.APK_BUILD_DIR
|
||||
run: |
|
||||
mkdir -p $APK_BUILD_DIR
|
||||
|
||||
+4
-1
@@ -15,7 +15,9 @@ import 'package:localsend_app/provider/dio_provider.dart';
|
||||
import 'package:localsend_app/provider/network/nearby_devices_provider.dart';
|
||||
import 'package:localsend_app/provider/network/server/server_provider.dart';
|
||||
import 'package:localsend_app/provider/persistence_provider.dart';
|
||||
// [FOSS_REMOVE_START]
|
||||
import 'package:localsend_app/provider/purchase_provider.dart';
|
||||
// [FOSS_REMOVE_END]
|
||||
import 'package:localsend_app/provider/selection/selected_sending_files_provider.dart';
|
||||
import 'package:localsend_app/provider/tv_provider.dart';
|
||||
import 'package:localsend_app/provider/window_dimensions_provider.dart';
|
||||
@@ -175,11 +177,12 @@ Future<void> postInit(BuildContext context, Ref ref, bool appStart, void Functio
|
||||
ref.dispatchAsync(ClearCacheAction()); // ignore: unawaited_futures
|
||||
}
|
||||
|
||||
|
||||
// [FOSS_REMOVE_START]
|
||||
if (checkPlatformSupportPayment()) {
|
||||
// ignore: unawaited_futures
|
||||
ref.redux(purchaseProvider).dispatchAsync(InitPurchaseStream());
|
||||
}
|
||||
// [FOSS_REMOVE_END]
|
||||
}
|
||||
|
||||
class _HandleShareIntentAction extends AsyncGlobalAction {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:dart_mappable/dart_mappable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:in_app_purchase/in_app_purchase.dart';
|
||||
|
||||
part 'purchase_state.mapper.dart';
|
||||
|
||||
@@ -36,7 +35,7 @@ enum PurchaseItem {
|
||||
@MappableClass()
|
||||
class PurchaseState with PurchaseStateMappable {
|
||||
final Map<PurchaseItem, String> prices;
|
||||
final Map<PurchaseItem, PurchaseDetails> purchases;
|
||||
final Set<PurchaseItem> purchases;
|
||||
final bool pending;
|
||||
|
||||
const PurchaseState({
|
||||
|
||||
@@ -23,10 +23,9 @@ class PurchaseStateMapper extends ClassMapperBase<PurchaseState> {
|
||||
static Map<PurchaseItem, String> _$prices(PurchaseState v) => v.prices;
|
||||
static const Field<PurchaseState, Map<PurchaseItem, String>> _f$prices =
|
||||
Field('prices', _$prices);
|
||||
static Map<PurchaseItem, PurchaseDetails> _$purchases(PurchaseState v) =>
|
||||
v.purchases;
|
||||
static const Field<PurchaseState, Map<PurchaseItem, PurchaseDetails>>
|
||||
_f$purchases = Field('purchases', _$purchases);
|
||||
static Set<PurchaseItem> _$purchases(PurchaseState v) => v.purchases;
|
||||
static const Field<PurchaseState, Set<PurchaseItem>> _f$purchases =
|
||||
Field('purchases', _$purchases);
|
||||
static bool _$pending(PurchaseState v) => v.pending;
|
||||
static const Field<PurchaseState, bool> _f$pending =
|
||||
Field('pending', _$pending);
|
||||
@@ -102,11 +101,9 @@ abstract class PurchaseStateCopyWith<$R, $In extends PurchaseState, $Out>
|
||||
implements ClassCopyWith<$R, $In, $Out> {
|
||||
MapCopyWith<$R, PurchaseItem, String, ObjectCopyWith<$R, String, String>>
|
||||
get prices;
|
||||
MapCopyWith<$R, PurchaseItem, PurchaseDetails,
|
||||
ObjectCopyWith<$R, PurchaseDetails, PurchaseDetails>> get purchases;
|
||||
$R call(
|
||||
{Map<PurchaseItem, String>? prices,
|
||||
Map<PurchaseItem, PurchaseDetails>? purchases,
|
||||
Set<PurchaseItem>? purchases,
|
||||
bool? pending});
|
||||
PurchaseStateCopyWith<$R2, $In, $Out2> $chain<$R2, $Out2>(Then<$Out2, $R2> t);
|
||||
}
|
||||
@@ -124,14 +121,9 @@ class _PurchaseStateCopyWithImpl<$R, $Out>
|
||||
get prices => MapCopyWith($value.prices,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t), (v) => call(prices: v));
|
||||
@override
|
||||
MapCopyWith<$R, PurchaseItem, PurchaseDetails,
|
||||
ObjectCopyWith<$R, PurchaseDetails, PurchaseDetails>>
|
||||
get purchases => MapCopyWith($value.purchases,
|
||||
(v, t) => ObjectCopyWith(v, $identity, t), (v) => call(purchases: v));
|
||||
@override
|
||||
$R call(
|
||||
{Map<PurchaseItem, String>? prices,
|
||||
Map<PurchaseItem, PurchaseDetails>? purchases,
|
||||
Set<PurchaseItem>? purchases,
|
||||
bool? pending}) =>
|
||||
$apply(FieldCopyWithData({
|
||||
if (prices != null) #prices: prices,
|
||||
|
||||
@@ -2,8 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:localsend_app/gen/strings.g.dart';
|
||||
import 'package:localsend_app/model/state/purchase_state.dart';
|
||||
import 'package:localsend_app/pages/donation/donation_page_vm.dart';
|
||||
// [FOSS_REMOVE_START]
|
||||
import 'package:localsend_app/provider/purchase_provider.dart';
|
||||
import 'package:localsend_app/util/native/platform_check.dart';
|
||||
// [FOSS_REMOVE_END]
|
||||
import 'package:localsend_app/widget/responsive_list_view.dart';
|
||||
import 'package:refena_flutter/refena_flutter.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
@@ -15,7 +16,9 @@ class DonationPage extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return ViewModelBuilder(
|
||||
provider: donationPageVmProvider,
|
||||
// [FOSS_REMOVE_START]
|
||||
init: (context, ref) => ref.redux(purchaseProvider).dispatchAsync(FetchPricesAndPurchasesAction()), // ignore: discarded_futures
|
||||
// [FOSS_REMOVE_END]
|
||||
builder: (context, vm) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@@ -45,7 +48,7 @@ class DonationPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (checkPlatformSupportPayment()) _StoreDonation(vm) else const _LinkDonation(),
|
||||
if (vm.platformSupportPayment) _StoreDonation(vm) else const _LinkDonation(),
|
||||
],
|
||||
),
|
||||
if (vm.pending)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import 'package:localsend_app/model/state/purchase_state.dart';
|
||||
// [FOSS_REMOVE_START]
|
||||
import 'package:localsend_app/provider/purchase_provider.dart';
|
||||
// [FOSS_REMOVE_END]
|
||||
import 'package:localsend_app/util/native/platform_check.dart';
|
||||
import 'package:refena_flutter/refena_flutter.dart';
|
||||
|
||||
class DonationPageVm {
|
||||
final bool platformSupportPayment;
|
||||
final Map<PurchaseItem, String> prices;
|
||||
final Set<PurchaseItem> purchased;
|
||||
final bool pending;
|
||||
@@ -10,6 +14,7 @@ class DonationPageVm {
|
||||
final void Function() restore;
|
||||
|
||||
DonationPageVm({
|
||||
required this.platformSupportPayment,
|
||||
required this.prices,
|
||||
required this.purchased,
|
||||
required this.pending,
|
||||
@@ -18,13 +23,29 @@ class DonationPageVm {
|
||||
});
|
||||
}
|
||||
|
||||
// [FOSS_REMOVE_START]
|
||||
final donationPageVmProvider = ViewProvider<DonationPageVm>((ref) {
|
||||
final state = ref.watch(purchaseProvider);
|
||||
return DonationPageVm(
|
||||
platformSupportPayment: checkPlatformSupportPayment(),
|
||||
prices: state.prices,
|
||||
purchased: state.purchases.keys.toSet(),
|
||||
purchased: state.purchases,
|
||||
pending: state.pending,
|
||||
purchase: (item) => ref.redux(purchaseProvider).dispatchAsync(PurchaseAction(item)),
|
||||
restore: () => ref.redux(purchaseProvider).dispatchAsync(PurchaseRestoreAction()),
|
||||
);
|
||||
});
|
||||
// [FOSS_REMOVE_END]
|
||||
|
||||
/// This is a noop version of the original view model.
|
||||
/// Used to compile the FOSS version of the app by removing the original provider above.
|
||||
final donationPageNoopVmProvider = ViewProvider<DonationPageVm>((ref) {
|
||||
return DonationPageVm(
|
||||
platformSupportPayment: false,
|
||||
prices: {},
|
||||
purchased: {},
|
||||
pending: false,
|
||||
purchase: (_) {},
|
||||
restore: () {},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -123,7 +123,7 @@ class AddPurchaseAction extends ReduxAction<PurchaseService, PurchaseState> {
|
||||
return state.copyWith(
|
||||
purchases: {
|
||||
...state.purchases,
|
||||
item: purchase,
|
||||
item,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ dependencies:
|
||||
flutter_markdown: 0.6.18+2
|
||||
gal: 2.1.4
|
||||
image_picker: 1.0.4
|
||||
in_app_purchase: 3.1.11
|
||||
in_app_purchase: 3.1.11 # [FOSS_REMOVE]
|
||||
intl: ^0.18.0 # allow newer versions, so it can compile with newer Flutter versions
|
||||
launch_at_startup: 0.2.2
|
||||
logging: 1.2.0
|
||||
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script removes proprietary dependencies from the project.
|
||||
|
||||
cd app
|
||||
|
||||
REGEX_A="s/\/\/ \[FOSS_REMOVE_START\]/\/*/"
|
||||
REGEX_B="s/\/\/ \[FOSS_REMOVE_END\]/\*\//"
|
||||
|
||||
# Remove lines from pubspec.yaml
|
||||
sed -i '/# \[FOSS_REMOVE\]/d' pubspec.yaml
|
||||
|
||||
# Comment out parts in Dart files
|
||||
sed -i "$REGEX_A" lib/init.dart
|
||||
sed -i "$REGEX_B" lib/init.dart
|
||||
|
||||
sed -i "$REGEX_A" lib/pages/donation/donation_page.dart
|
||||
sed -i "$REGEX_B" lib/pages/donation/donation_page.dart
|
||||
|
||||
sed -i "$REGEX_A" lib/pages/donation/donation_page_vm.dart
|
||||
sed -i "$REGEX_B" lib/pages/donation/donation_page_vm.dart
|
||||
|
||||
# Remove files completely
|
||||
rm lib/provider/purchase_provider.dart
|
||||
|
||||
# Refer to donationPageNoopVmProvider instead of donationPageVmProvider
|
||||
sed -i 's/donationPageVmProvider/donationPageNoopVmProvider/g' lib/pages/donation/donation_page.dart
|
||||
|
||||
cd ..
|
||||
echo "Proprietary dependencies removed."
|
||||
Reference in New Issue
Block a user