Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter Web Adjustments #105

Merged
merged 11 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/ui_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ jobs:
# 1) Check out repo
- uses: actions/checkout@v3

# 2) Create google-services.json if you have it in a secret
# 2a) Create google-services.json if you have it in a secret
- name: Create google-services.json
run: |
cat <<EOF > android/app/google-services.json
${{ secrets.GOOGLE_SERVICES_JSON }}
EOF

# 2b) Create firebase-options.dart if you have it in a secret
- name: Create firebase-options.dart
run: |
cat <<EOF > lib/firebase_options.dart
${{ secrets.FIREBASE_OPTIONS_DART }}
EOF

# 3) Install Flutter
- name: Set up Flutter
uses: subosito/flutter-action@v2
Expand Down
7 changes: 4 additions & 3 deletions .idea/libraries/Flutter_Plugins.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 0 additions & 82 deletions .idea/telnyx-webrtc-flutter.iml

This file was deleted.

30 changes: 30 additions & 0 deletions .metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 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: "dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
- platform: web
create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668
base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
17 changes: 17 additions & 0 deletions flutter_voice_sdk.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
3 changes: 3 additions & 0 deletions integration_test/patrol_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ void main() {
($) async {
// 1. Start the app using Patrol
await $.pumpWidgetAndSettle(const MyApp());

// Wait for app to launch and grand permission
await Future.delayed(const Duration(seconds: 3));
await $.native.grantPermissionWhenInUse();

// 2. Open the bottom sheet by pressing "Switch Profile"
Expand Down
20 changes: 15 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import 'package:telnyx_webrtc/model/socket_method.dart';
import 'package:telnyx_flutter_webrtc/utils/theme.dart';
import 'package:telnyx_webrtc/config/telnyx_config.dart';

import 'package:telnyx_flutter_webrtc/firebase_options.dart';

final logger = Logger();
final txClientViewModel = TelnyxClientViewModel();
const MOCK_USER = '<MOCK_USER>';
Expand Down Expand Up @@ -136,13 +138,16 @@ class AppInitializer {
}

/// Firebase
await Firebase.initializeApp();
if (Platform.isAndroid) {
await Firebase.initializeApp(
options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null,
);
if (!kIsWeb && Platform.isAndroid) {
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler,
);
} else {
logger.i('iOS - Skipping Firebase Messaging onBackgroundMessage');
logger
.i('Web or iOS - Skipping Firebase Messaging onBackgroundMessage');
}

if (defaultTargetPlatform == TargetPlatform.android) {
Expand All @@ -165,7 +170,9 @@ var fromBackground = false;
// Android Only - Push Notifications
@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
await Firebase.initializeApp(
options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null,
);
logger.i('Handling a background message ${message.toMap().toString()}');
await NotificationService.showNotification(message);
FlutterCallkitIncoming.onEvent.listen((CallEvent? event) async {
Expand Down Expand Up @@ -280,6 +287,7 @@ Future<void> main() async {
final config = await txClientViewModel.getConfig();
runApp(
BackgroundDetector(
skipWeb: true,
onLifecycleEvent: (AppLifecycleState state) => {
if (state == AppLifecycleState.resumed)
{
Expand Down Expand Up @@ -390,8 +398,10 @@ class _MyAppState extends State<MyApp> {
logger.d('getPushData : No data');
}
});
} else if (Platform.isIOS && !txClientViewModel.callFromPush) {
} else if (!kIsWeb && Platform.isIOS && !txClientViewModel.callFromPush) {
logger.i('iOS :: connect');
} else {
logger.i('Web :: connect');
}
} catch (e) {
logger.e('Error: $e');
Expand Down
10 changes: 9 additions & 1 deletion lib/model/profile_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:telnyx_flutter_webrtc/firebase_options.dart';
import 'package:telnyx_webrtc/config/telnyx_config.dart';

class Profile {
Expand Down Expand Up @@ -51,10 +52,17 @@ class Profile {

Future<String?> getNotificationTokenForPlatform() async {
var token;

if (kIsWeb) {
return null;
}

if (defaultTargetPlatform == TargetPlatform.android) {
// If no apps are initialized, initialize one now.
if (Firebase.apps.isEmpty) {
await Firebase.initializeApp();
await Firebase.initializeApp(
options: kIsWeb ? DefaultFirebaseOptions.currentPlatform : null,
);
}
token = (await FirebaseMessaging.instance.getToken())!;
} else if (Platform.isIOS) {
Expand Down
10 changes: 10 additions & 0 deletions lib/utils/background_detector.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class BackgroundDetector extends StatefulWidget {
static BackgroundDetector? _instance;

static bool _skipWeb = false;

static bool get skipWeb => _skipWeb;
static set skipWeb(bool value) => _skipWeb = value;

factory BackgroundDetector({
Key? key,
bool skipWeb = false,
required Widget child,
void Function(AppLifecycleState)? onLifecycleEvent,
}) {
_skipWeb = skipWeb;
_instance ??= BackgroundDetector._internal(
key: key,
onLifecycleEvent: onLifecycleEvent,
Expand All @@ -35,6 +43,7 @@ class BackgroundDetector extends StatefulWidget {

/// Whether to globally ignore lifecycle events
static bool get ignore => _ignoreLifecycleEvents;

static set ignore(bool value) => _ignoreLifecycleEvents = value;

/// Temporarily ignore lifecycle events during [action].
Expand Down Expand Up @@ -69,6 +78,7 @@ class _BackgroundDetectorState extends State<BackgroundDetector>

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (BackgroundDetector.skipWeb == true && kIsWeb) return;
// Only emit if NOT ignoring
if (!BackgroundDetector.ignore) {
widget.onLifecycleEvent?.call(state);
Expand Down
13 changes: 9 additions & 4 deletions lib/view/screen/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';
import 'package:permission_handler/permission_handler.dart';
Expand All @@ -23,10 +24,14 @@ class _HomeScreenState extends State<HomeScreen> {
}

Future<void> askForNotificationPermission() async {
await FlutterCallkitIncoming.requestNotificationPermission('notification');
final status = await Permission.notification.status;
if (status.isDenied) {
await Permission.notification.request();
if (!kIsWeb) {
await FlutterCallkitIncoming.requestNotificationPermission(
'notification',
);
final status = await Permission.notification.status;
if (status.isDenied) {
await Permission.notification.request();
}
}
}

Expand Down
Loading
Loading