Vishnu Mohandas 1 år sedan
förälder
incheckning
f73df1f8b7

+ 3 - 0
.gitmodules

@@ -6,3 +6,6 @@
 	path = flutter
 	url = https://github.com/flutter/flutter.git
 	branch = stable
+[submodule "assets/simple-icons"]
+	path = assets/simple-icons
+	url = https://github.com/simple-icons/simple-icons.git

+ 8 - 0
README.md

@@ -101,6 +101,14 @@ For maintainers, there is [additional documentation](RELEASES.md) on
 automatically publishing the main branch to App store, Play store and GitHub
 releases.
 
+## 🙂 Icons
+
+ente Auth supports the icon pack provided by
+[simple-icons](https://github.com/simple-icons/simple-icons).
+
+If you would like to add your own custom icon, please create a pull-request with
+an SVG for your service that matches the contents within `assets/custom-icons`.
+
 ## 🙋‍♂️ Support
 
 If you need help, please reach out to support@ente.io, and a human will get in

+ 1 - 0
assets/build/.last_build_id

@@ -0,0 +1 @@
+f23611a675a8c9bc71eb16e8a1108cf8

+ 8 - 0
assets/custom-icons/_data/custom-icons.json

@@ -0,0 +1,8 @@
+{
+    "icons": [
+        {
+            "title": "ente",
+            "hex": "1DB954"
+        }
+    ]
+}

+ 3 - 0
assets/custom-icons/icons/ente.svg

@@ -0,0 +1,3 @@
+<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.06803 7.096C3.33203 7.096 2.68403 6.952 2.12403 6.664C1.57203 6.376 1.14403 5.984 0.840033 5.488C0.536033 4.984 0.384033 4.412 0.384033 3.772C0.384033 3.124 0.532033 2.552 0.828033 2.056C1.13203 1.552 1.54403 1.16 2.06403 0.879997C2.58403 0.591998 3.17203 0.447998 3.82803 0.447998C4.46003 0.447998 5.02803 0.583998 5.53203 0.855998C6.04403 1.12 6.44803 1.504 6.74403 2.008C7.04003 2.504 7.18803 3.1 7.18803 3.796C7.18803 3.868 7.18403 3.952 7.17603 4.048C7.16803 4.136 7.16003 4.22 7.15203 4.3H1.90803V3.208H6.16803L5.44803 3.532C5.44803 3.196 5.38003 2.904 5.24403 2.656C5.10803 2.408 4.92003 2.216 4.68003 2.08C4.44003 1.936 4.16003 1.864 3.84003 1.864C3.52003 1.864 3.23603 1.936 2.98803 2.08C2.74803 2.216 2.56003 2.412 2.42403 2.668C2.28803 2.916 2.22003 3.212 2.22003 3.556V3.844C2.22003 4.196 2.29603 4.508 2.44803 4.78C2.60803 5.044 2.82803 5.248 3.10803 5.392C3.39603 5.528 3.73203 5.596 4.11603 5.596C4.46003 5.596 4.76003 5.544 5.01603 5.44C5.28003 5.336 5.52003 5.18 5.73603 4.972L6.73203 6.052C6.43603 6.388 6.06403 6.648 5.61603 6.832C5.16803 7.008 4.65203 7.096 4.06803 7.096Z" fill="black" style="fill:black;fill:black;fill-opacity:1;"/>
+</svg>

+ 1 - 0
assets/simple-icons

@@ -0,0 +1 @@
+Subproject commit 7e1ad4517598f36ba625741a4dfbc33610d105d8

+ 2 - 0
lib/main.dart

@@ -17,6 +17,7 @@ import 'package:ente_auth/services/user_service.dart';
 import 'package:ente_auth/store/code_store.dart';
 import 'package:ente_auth/ui/tools/app_lock.dart';
 import 'package:ente_auth/ui/tools/lock_screen.dart';
+import 'package:ente_auth/ui/utils/icon_utils.dart';
 import 'package:ente_auth/utils/crypto_util.dart';
 import 'package:flutter/foundation.dart';
 import "package:flutter/material.dart";
@@ -85,4 +86,5 @@ Future<void> _init(bool bool, {String? via}) async {
   await BillingService.instance.init();
   await NotificationService.instance.init();
   await UpdateService.instance.init();
+  await IconUtils.instance.init();
 }

+ 27 - 14
lib/ui/code_widget.dart

@@ -8,6 +8,7 @@ import 'package:ente_auth/onboarding/view/setup_enter_secret_key_page.dart';
 import 'package:ente_auth/onboarding/view/view_qr_page.dart';
 import 'package:ente_auth/store/code_store.dart';
 import 'package:ente_auth/ui/code_timer_progress.dart';
+import 'package:ente_auth/ui/utils/icon_utils.dart';
 import 'package:ente_auth/utils/dialog_util.dart';
 import 'package:ente_auth/utils/toast_util.dart';
 import 'package:ente_auth/utils/totp_util.dart';
@@ -81,7 +82,7 @@ class _CodeWidgetState extends State<CodeWidget> {
               backgroundColor: Colors.grey.withOpacity(0.1),
               borderRadius: const BorderRadius.all(Radius.circular(12.0)),
               foregroundColor:
-              Theme.of(context).colorScheme.inverseBackgroundColor,
+                  Theme.of(context).colorScheme.inverseBackgroundColor,
               icon: Icons.qr_code_2_outlined,
               label: "QR",
               padding: const EdgeInsets.only(left: 4, right: 0),
@@ -90,7 +91,6 @@ class _CodeWidgetState extends State<CodeWidget> {
             const SizedBox(
               width: 4,
             ),
-
             SlidableAction(
               onPressed: _onEditPressed,
               backgroundColor: Colors.grey.withOpacity(0.1),
@@ -171,14 +171,23 @@ class _CodeWidgetState extends State<CodeWidget> {
                                 ),
                               ],
                             ),
-                            widget.code.hasSynced != null &&
-                                    widget.code.hasSynced!
-                                ? Container()
-                                : const Icon(
-                                    Icons.sync_disabled,
-                                    size: 20,
-                                    color: Colors.amber,
-                                  ),
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.end,
+                              children: [
+                                widget.code.hasSynced != null &&
+                                        widget.code.hasSynced!
+                                    ? Container()
+                                    : const Icon(
+                                        Icons.sync_disabled,
+                                        size: 20,
+                                        color: Colors.amber,
+                                      ),
+                                const SizedBox(width: 12),
+                                IconUtils.instance.getIcon(
+                                  safeDecode(widget.code.issuer).trim(),
+                                ),
+                              ],
+                            ),
                           ],
                         ),
                       ),
@@ -231,7 +240,7 @@ class _CodeWidgetState extends State<CodeWidget> {
                                         style:
                                             Theme.of(context).textTheme.caption,
                                       ),
-                                       InkWell(
+                                      InkWell(
                                         onTap: _onNextHotpTapped,
                                         child: const Icon(
                                           Icons.forward_outlined,
@@ -264,8 +273,13 @@ class _CodeWidgetState extends State<CodeWidget> {
   }
 
   void _onNextHotpTapped() {
-    if(widget.code.type == Type.hotp) {
-     CodeStore.instance.addCode(widget.code.copyWith(counter: widget.code.counter + 1), shouldSync: true).ignore();
+    if (widget.code.type == Type.hotp) {
+      CodeStore.instance
+          .addCode(
+            widget.code.copyWith(counter: widget.code.counter + 1),
+            shouldSync: true,
+          )
+          .ignore();
     }
   }
 
@@ -306,7 +320,6 @@ class _CodeWidgetState extends State<CodeWidget> {
     );
   }
 
-
   String _getCurrentOTP() {
     try {
       return getOTP(widget.code);

+ 70 - 0
lib/ui/utils/icon_utils.dart

@@ -0,0 +1,70 @@
+import 'dart:convert';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/svg.dart';
+
+class IconUtils {
+  IconUtils._privateConstructor();
+
+  static final IconUtils instance = IconUtils._privateConstructor();
+
+  // Map of icon-title to the color code in HEX
+  final Map<String, String> _simpleIcons = {};
+  final Map<String, String> _customIcons = {};
+
+  Future<void> init() async {
+    await _loadJson();
+  }
+
+  Widget getIcon(String provider) {
+    final title = _getProviderTitle(provider);
+    if (_simpleIcons.containsKey(title)) {
+      return _getSVGIcon(
+        "assets/simple-icons/icons/$title.svg",
+        title,
+        _simpleIcons[title]!,
+      );
+    } else if (_customIcons.containsKey(title)) {
+      return _getSVGIcon(
+        "assets/custom-icons/icons/$title.svg",
+        title,
+        _customIcons[title]!,
+      );
+    } else {
+      return Text(title);
+    }
+  }
+
+  Widget _getSVGIcon(String path, String title, String color) {
+    return SvgPicture.asset(
+      path,
+      width: 24,
+      semanticsLabel: title,
+      colorFilter: ColorFilter.mode(
+        Color(int.parse("0xFF" + color)),
+        BlendMode.srcIn,
+      ),
+    );
+  }
+
+  Future<void> _loadJson() async {
+    final simpleIconData = await rootBundle
+        .loadString('assets/simple-icons/_data/simple-icons.json');
+    final simpleIcons = json.decode(simpleIconData);
+    for (final icon in simpleIcons["icons"]) {
+      _simpleIcons[icon["title"].toString().toLowerCase()] = icon["hex"];
+    }
+    final customIconData = await rootBundle
+        .loadString('assets/custom-icons/_data/custom-icons.json');
+    final customIcons = json.decode(customIconData);
+    for (final icon in customIcons["icons"]) {
+      _customIcons[icon["title"].toString().toLowerCase()] = icon["hex"];
+    }
+  }
+
+  String _getProviderTitle(String provider) {
+    return provider.split(".")[0].toLowerCase();
+  }
+}

+ 32 - 0
pubspec.lock

@@ -589,6 +589,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.2.0"
+  flutter_svg:
+    dependency: "direct main"
+    description:
+      name: flutter_svg
+      sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.5"
   flutter_test:
     dependency: "direct dev"
     description: flutter
@@ -1556,6 +1564,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.7"
+  vector_graphics:
+    dependency: transitive
+    description:
+      name: vector_graphics
+      sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.5"
+  vector_graphics_codec:
+    dependency: transitive
+    description:
+      name: vector_graphics_codec
+      sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.5"
+  vector_graphics_compiler:
+    dependency: transitive
+    description:
+      name: vector_graphics_compiler
+      sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca"
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.1.5"
   vector_math:
     dependency: transitive
     description:

+ 5 - 0
pubspec.yaml

@@ -44,6 +44,7 @@ dependencies:
     git:
       url: https://github.com/ente-io/flutter_sodium.git
   flutter_speed_dial: ^6.2.0
+  flutter_svg: ^2.0.5
   fluttertoast: ^8.1.1
   google_nav_bar: ^5.0.5 #supported
   http: ^0.13.4
@@ -92,6 +93,10 @@ flutter:
   # https://docs:flutter:dev/development/ui/assets-and-images:
   assets:
     - assets/
+    - assets/simple-icons/icons/
+    - assets/simple-icons/_data/
+    - assets/custom-icons/icons/
+    - assets/custom-icons/_data/
 
   fonts:
     - family: Inter

BIN
screenshots/screenshots.png