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

feat: ✨ Web support #164

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
324 changes: 162 additions & 162 deletions example/pubspec.lock

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions lib/pages/get_wallet_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:url_launcher/url_launcher.dart';
Expand Down Expand Up @@ -49,9 +50,11 @@ class GetWalletPage extends StatelessWidget {
return WalletsList(
itemList: itemsToShow,
onTapWallet: (data) {
final url = Platform.isIOS
? data.listing.appStore
: data.listing.playStore;
final url = kIsWeb
? data.listing.webappLink
: Platform.isIOS
? data.listing.appStore
: data.listing.playStore;
if ((url ?? '').isNotEmpty) {
urlUtils.instance.launchUrl(
Uri.parse(url!),
Expand Down
27 changes: 18 additions & 9 deletions lib/services/explorer_service/explorer_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
Expand Down Expand Up @@ -201,7 +200,7 @@ class ExplorerService implements IExplorerService {
_core.projectId,
_referer,
);
final uri = Platform.isIOS
final uri = platformUtils.instance.getPlatformExact() == PlatformExact.iOS
? Uri.parse('${UrlConstants.apiService}/getIosData')
: Uri.parse('${UrlConstants.apiService}/getAndroidData');
try {
Expand All @@ -211,7 +210,12 @@ class ExplorerService implements IExplorerService {
jsonDecode(response.body),
(json) => NativeAppData.fromJson(json),
);
return apiResponse.data.toList();
final result = apiResponse.data.toList();
loggerService.instance.d(
'[$runtimeType] fetched native data : ${result.map((appData) => jsonEncode(appData.toJson()))}',
error: response.statusCode,
);
return result;
} else {
loggerService.instance.d(
'⛔ [$runtimeType] error fetching native data $uri',
Expand Down Expand Up @@ -423,6 +427,9 @@ class ExplorerService implements IExplorerService {

@override
Future<W3MWalletInfo?> getCoinbaseWalletObject() async {
if (platformUtils.instance.getPlatformType() == PlatformType.web) {
return null;
}
final results = await _fetchListings(
params: RequestParams(
page: 1,
Expand Down Expand Up @@ -486,15 +493,17 @@ class ExplorerService implements IExplorerService {

String _getPlatformType() {
final type = platformUtils.instance.getPlatformType();
final exactPlatform = platformUtils.instance.getPlatformExact();
final platform = type.toString().toLowerCase();
switch (type) {
case PlatformType.mobile:
if (Platform.isIOS) {
return 'ios';
} else if (Platform.isAndroid) {
return 'android';
} else {
return 'mobile';
switch (exactPlatform) {
case PlatformExact.iOS:
return 'ios';
case PlatformExact.android:
return 'android';
default:
return 'mobile';
}
default:
return platform;
Expand Down
10 changes: 8 additions & 2 deletions lib/services/logger_service/logger_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,18 @@ class LoggerService implements ILoggerService {
level: level.toLevel(),
printer: PrettyPrinter(methodCount: null),
);
if (debugMode && level == LogLevel.error) {
if (debugMode) {
Logger.addLogListener(_logListener);
}
}

void _logListener(LogEvent event) => debugPrint('${event.message}');
void _logListener(LogEvent event) {
debugPrint('${event.message}');
if (event.error != null) debugPrint('Exception : ${event.error}');
if (event.stackTrace != null) {
debugPrint('Stacktrace :\n${event.stackTrace}');
}
}

@override
void d(
Expand Down
5 changes: 3 additions & 2 deletions lib/utils/core/core_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ class CoreUtils extends ICoreUtils {
'x-project-id': projectId,
'x-sdk-type': StringConstants.X_SDK_TYPE,
'x-sdk-version': 'flutter-${StringConstants.X_SDK_VERSION}',
'user-agent': getUserAgent(),
if (referer != null) 'referer': referer,
// Following headers are rejected by some web browsers (i.e. Safari)
// 'user-agent': getUserAgent(),
// if (referer != null) 'referer': referer,
};
}
}
24 changes: 16 additions & 8 deletions lib/utils/platform/platform_utils.dart
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb;
import 'package:web3modal_flutter/utils/platform/i_platform_utils.dart';

class PlatformUtils extends IPlatformUtils {
bool get _runsOnIos =>
(kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) ||
(!kIsWeb && Platform.isIOS);
bool get _runsOnAndroid =>
(kIsWeb && defaultTargetPlatform == TargetPlatform.android) ||
(!kIsWeb && Platform.isAndroid);

@override
PlatformExact getPlatformExact() {
if (Platform.isAndroid) {
if (_runsOnAndroid) {
return PlatformExact.android;
} else if (Platform.isIOS) {
} else if (_runsOnIos) {
return PlatformExact.iOS;
} else if (kIsWeb) {
return PlatformExact.web;
} else if (Platform.isLinux) {
return PlatformExact.linux;
} else if (Platform.isMacOS) {
return PlatformExact.macOS;
} else if (Platform.isWindows) {
return PlatformExact.windows;
} else if (kIsWeb) {
return PlatformExact.web;
}
return PlatformExact.web;
}

@override
PlatformType getPlatformType() {
if (Platform.isAndroid || Platform.isIOS) {
if (_runsOnAndroid || _runsOnIos) {
return PlatformType.mobile;
} else if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
} else if (!kIsWeb &&
(Platform.isLinux || Platform.isMacOS || Platform.isWindows)) {
return PlatformType.desktop;
} else if (kIsWeb) {
return PlatformType.web;
Expand All @@ -37,7 +45,7 @@ class PlatformUtils extends IPlatformUtils {

@override
bool canDetectInstalledApps() {
return getPlatformType() == PlatformType.mobile;
return !kIsWeb && getPlatformType() == PlatformType.mobile;
}

@override
Expand Down
33 changes: 17 additions & 16 deletions lib/utils/url/url_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,24 @@ class UrlUtils extends IUrlUtils {
return false;
}

if (platformUtils.instance.canDetectInstalledApps()) {
final p = platformUtils.instance.getPlatformExact();
try {
if (p == PlatformExact.android) {
return await androidAppCheck(uri);
} else if (p == PlatformExact.iOS) {
return await canLaunchUrlFunc(Uri.parse(uri));
}
} on FormatException catch (e) {
if (id != null) {
loggerService.instance.d('[$runtimeType] $uri ($id): ${e.message}');
} else {
loggerService.instance.d('[$runtimeType] $uri: ${e.message}');
}
} catch (e) {
rethrow;
final p = platformUtils.instance.getPlatformExact();
if (!platformUtils.instance.canDetectInstalledApps()) {
return false;
}
try {
if (p == PlatformExact.android) {
return await androidAppCheck(uri);
} else if (p == PlatformExact.iOS) {
return await canLaunchUrlFunc(Uri.parse(uri));
}
} on FormatException catch (e) {
if (id != null) {
loggerService.instance.d('[$runtimeType] $uri ($id): ${e.message}');
} else {
loggerService.instance.d('[$runtimeType] $uri: ${e.message}');
}
} catch (e) {
rethrow;
}

return false;
Expand Down
3 changes: 3 additions & 0 deletions lib/widgets/avatars/w3m_wallet_avatar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:web3modal_flutter/services/explorer_service/explorer_service_singleton.dart';
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
import 'package:web3modal_flutter/theme/w3m_theme.dart';
import 'package:web3modal_flutter/utils/core/core_utils_singleton.dart';

Expand Down Expand Up @@ -75,6 +76,8 @@ class W3MListAvatar extends StatelessWidget {
),
child: CachedNetworkImage(
imageUrl: imageUrl!,
// Workaround for https://github.com/Baseflow/flutter_cached_network_image/issues/820
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet,
httpHeaders: coreUtils.instance.getAPIHeaders(projectId),
fadeInDuration: const Duration(milliseconds: 500),
fadeOutDuration: const Duration(milliseconds: 500),
Expand Down
5 changes: 3 additions & 2 deletions lib/widgets/lists/list_items/download_wallet_item.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';

Expand All @@ -21,10 +22,10 @@ class DownloadWalletItem extends StatelessWidget {
if (webOnly) {
return walletInfo.listing.homepage;
}
if (Platform.isIOS) {
if (!kIsWeb && Platform.isIOS) {
return walletInfo.listing.appStore ?? '';
}
if (Platform.isAndroid) {
if (!kIsWeb && Platform.isAndroid) {
return walletInfo.listing.playStore ?? '';
}
return '';
Expand Down
Loading