~cytrogen/fluent-reader-mobile

ref: 0b77b4664f92ca4fce2f347c33fc4298f7bf9c26 fluent-reader-mobile/lib/utils/utils.dart -rw-r--r-- 2.0 KiB
0b77b466 — 刘浩远 add feedbin support 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import 'dart:math';

import 'package:fluent_reader_lite/generated/l10n.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:url_launcher/url_launcher.dart';

abstract class Utils {
  static final syncMaxId = pow(2, 50);

  static void openExternal(String url) {
    launch(url, forceSafariVC: false, forceWebView: false);
  }

  static int binarySearch<T>(List<T> sortedList, T value, 
    int Function(T, T) compare) {
    var min = 0;
    var max = sortedList.length;
    while (min < max) {
      var mid = min + ((max - min) >> 1);
      var element = sortedList[mid];
      var comp = compare(element, value);
      if (comp == 0) return mid;
      if (comp < 0) {
        min = mid + 1;
      } else {
        max = mid;
      }
    }
    return min;
  }

  static Future<bool> validateFavicon(String url) async {
    var flag = false;
    try {
      var result = await http.get(url);
      if (result.statusCode == 200) {
        var contentType = result.headers["Content-Type"] ?? result.headers["content-type"];
        if (contentType != null && contentType.startsWith("image")) flag = true;
      }
    } finally {
      return flag;
    }
  }

  static final _urlRegex = RegExp(
    r"^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*$)",
    caseSensitive: false,
  );
  static bool testUrl(String url) => _urlRegex.hasMatch(url.trim());

  static bool notEmpty(String text) => text.trim().length > 0;

  static void showServiceFailureDialog(BuildContext context) {
    showCupertinoDialog(
      context: context,
      builder: (context) => CupertinoAlertDialog(
        title: Text(S.of(context).serviceFailure),
        content: Text(S.of(context).serviceFailureHint),
        actions: [
          CupertinoDialogAction(
            child: Text(S.of(context).close),
            onPressed: () { Navigator.of(context).pop(); },
          ),
        ],
      ),
    );
  }
}