fix lints
This commit is contained in:
@@ -17,16 +17,15 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
library;
|
||||
|
||||
/// Curated picker options for the web-search language and country selectors.
|
||||
///
|
||||
/// Codes intersect what Brave (`search_lang`/`country`) and Mojeek
|
||||
/// (`lb`/`rb`) accept; English display names so the menu doesn't need a
|
||||
/// per-locale translation pass. The protocol carries just the primary
|
||||
/// ISO 639-1 / ISO 3166-1 alpha-2 codes — region qualifiers (`en-gb`,
|
||||
/// `pt-br`, etc.) are reconstructed server-side from the language+country
|
||||
/// pair.
|
||||
// Curated picker options for the web-search language and country selectors.
|
||||
//
|
||||
// Codes intersect what Brave (`search_lang`/`country`) and Mojeek
|
||||
// (`lb`/`rb`) accept; English display names so the menu doesn't need a
|
||||
// per-locale translation pass. The protocol carries just the primary
|
||||
// ISO 639-1 / ISO 3166-1 alpha-2 codes — region qualifiers (`en-gb`,
|
||||
// `pt-br`, etc.) are reconstructed server-side from the language+country
|
||||
// pair.
|
||||
|
||||
class LanguageOption {
|
||||
final String code; // ISO 639-1
|
||||
|
||||
+7
-13
@@ -3,7 +3,6 @@ import 'dart:async';
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart'
|
||||
as fmc;
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:search_client/search_client.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart';
|
||||
@@ -18,9 +17,9 @@ import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/providers.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/controllers/search_token_issuance_controller.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/providers.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/providers/proxy_client.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/repositories/search_token_stash_repository.dart';
|
||||
import 'package:weblibre/features/user/domain/repositories/cache.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/providers/proxy_client.dart';
|
||||
import 'package:weblibre/features/web_search/domain/services/capture_artifact_downloader.dart';
|
||||
import 'package:weblibre/features/web_search/domain/services/capture_server.dart';
|
||||
import 'package:weblibre/features/web_search/domain/services/sandbox_capture_store.dart';
|
||||
@@ -114,7 +113,7 @@ SandboxCaptureStore sandboxCaptureStore(Ref ref) => SandboxCaptureStore();
|
||||
@Riverpod(keepAlive: true)
|
||||
Stream<SandboxCaptureError> sandboxCaptureErrors(Ref ref) {
|
||||
final ctrl = ref.watch(sandboxCaptureControllerProvider.notifier);
|
||||
return ctrl.errors;
|
||||
return ctrl.errorStream();
|
||||
}
|
||||
|
||||
/// Orchestrates sandbox capture browsing:
|
||||
@@ -148,10 +147,7 @@ class SandboxCaptureController extends _$SandboxCaptureController {
|
||||
static const _defaultMethod = 'singlefile';
|
||||
static const _defaultVariant = 'balanced';
|
||||
|
||||
StreamSubscription<List<CaptureTabData>>? _captureTabSub;
|
||||
StreamSubscription<RetryRequest>? _retrySub;
|
||||
|
||||
Stream<SandboxCaptureError> get errors => _errors.stream;
|
||||
Stream<SandboxCaptureError> errorStream() => _errors.stream;
|
||||
|
||||
@override
|
||||
void build() {
|
||||
@@ -159,9 +155,9 @@ class SandboxCaptureController extends _$SandboxCaptureController {
|
||||
fmc.SandboxCaptureHostEvents.setUp(_hostEvents);
|
||||
|
||||
final dao = ref.read(tabDatabaseProvider).captureTabDao;
|
||||
_captureTabSub = dao.watchAll().listen(_onCaptureTabChange);
|
||||
final captureTabSub = dao.watchAll().listen(_onCaptureTabChange);
|
||||
|
||||
_retrySub = ref
|
||||
final retrySub = ref
|
||||
.read(captureServerProvider)
|
||||
.retryRequests
|
||||
.listen(_onRetryRequest);
|
||||
@@ -173,10 +169,8 @@ class SandboxCaptureController extends _$SandboxCaptureController {
|
||||
// stream — otherwise an in-flight Pigeon event or DAO emit could
|
||||
// race with handler cleanup, or _markFailed could try to add to a
|
||||
// closed _errors sink.
|
||||
final captureTabSub = _captureTabSub;
|
||||
final retrySub = _retrySub;
|
||||
if (captureTabSub != null) unawaited(captureTabSub.cancel());
|
||||
if (retrySub != null) unawaited(retrySub.cancel());
|
||||
unawaited(captureTabSub.cancel());
|
||||
unawaited(retrySub.cancel());
|
||||
fmc.SandboxCaptureHostEvents.setUp(null);
|
||||
_hostEvents.controller = null;
|
||||
unawaited(_errors.close());
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'dart:typed_data';
|
||||
|
||||
import 'package:riverpod/riverpod.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:search_client/search_client.dart';
|
||||
import 'package:weblibre/domain/services/generic_website.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/controllers/search_token_issuance_controller.dart';
|
||||
@@ -1226,7 +1225,10 @@ class WebSearchScrollOffset extends _$WebSearchScrollOffset {
|
||||
@override
|
||||
double build() => 0;
|
||||
|
||||
void update(double offset) => state = offset;
|
||||
void update(double offset) {
|
||||
if (state == offset) return;
|
||||
state = offset;
|
||||
}
|
||||
|
||||
void reset() => state = 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'dart:ui';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:search_protocol/search_protocol.dart';
|
||||
import 'package:search_client/search_client.dart';
|
||||
import 'package:weblibre/core/filesystem.dart';
|
||||
import 'package:weblibre/features/search_credits/domain/providers.dart';
|
||||
|
||||
@@ -361,14 +361,14 @@ class CaptureServer {
|
||||
final tabIdJson = jsonEncode(tabId);
|
||||
final captureIdJson = jsonEncode(captureId);
|
||||
final html =
|
||||
'<!doctype html><html><head><meta charset="utf-8">'
|
||||
'<meta name="viewport" content="width=device-width,initial-scale=1">'
|
||||
'<title>Capturing…</title><style>$_loaderStyles</style>'
|
||||
'</head><body>$body'
|
||||
'<script>window.__TAB_ID__=$tabIdJson;'
|
||||
'window.__CAPTURE_ID__=$captureIdJson;</script>'
|
||||
'<script>$_loaderScript</script>'
|
||||
'</body></html>';
|
||||
'''
|
||||
<!doctype html><html><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>Capturing…</title><style>$_loaderStyles</style>
|
||||
</head><body>$body
|
||||
<script>window.__TAB_ID__=$tabIdJson;window.__CAPTURE_ID__=$captureIdJson;</script>
|
||||
<script>$_loaderScript</script>
|
||||
</body></html>''';
|
||||
request.response.write(html);
|
||||
await request.response.close();
|
||||
}
|
||||
@@ -510,35 +510,24 @@ class CaptureServer {
|
||||
"base-uri 'none'; "
|
||||
"form-action 'self'";
|
||||
|
||||
static const _loaderStyles =
|
||||
'html,body{height:100%}'
|
||||
'body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,'
|
||||
'sans-serif;display:flex;align-items:center;justify-content:center;'
|
||||
'min-height:100vh;margin:0;background:#0b0d10;color:#e6e8eb}'
|
||||
'main{text-align:center;max-width:480px;padding:32px;opacity:0;'
|
||||
'animation:fade .35s ease-out forwards}'
|
||||
'@keyframes fade{to{opacity:1}}'
|
||||
'.spinner{width:56px;height:56px;margin:0 auto 20px;border-radius:50%;'
|
||||
'border:3px solid rgba(255,255,255,.08);border-top-color:#7aa2f7;'
|
||||
'animation:spin 1s linear infinite}'
|
||||
'@keyframes spin{to{transform:rotate(360deg)}}'
|
||||
'h1{font-size:18px;font-weight:600;margin:0 0 8px;letter-spacing:.2px}'
|
||||
'p{margin:0;color:#9aa1a8;font-size:14px;line-height:1.5}'
|
||||
'.dots::after{display:inline-block;width:1.2em;text-align:left;'
|
||||
'animation:dots 1.4s steps(4,end) infinite;content:""}'
|
||||
'@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}'
|
||||
'75%{content:"..."}100%{content:""}}'
|
||||
'.error h1{color:#f7768e}'
|
||||
'.actions{margin-top:20px;display:flex;gap:8px;justify-content:center}'
|
||||
'.btn{padding:10px 16px;border:0;border-radius:10px;cursor:pointer;'
|
||||
'font:inherit;font-weight:600;background:#7aa2f7;color:#0b0d10}'
|
||||
'.btn.secondary{background:transparent;color:#9aa1a8;'
|
||||
'border:1px solid rgba(255,255,255,.12)}'
|
||||
'.hidden{display:none}'
|
||||
'@media(prefers-color-scheme:light){body{background:#f5f6f8;'
|
||||
'color:#1a1d22}.spinner{border-color:rgba(0,0,0,.08);'
|
||||
'border-top-color:#3b82f6}.btn{background:#3b82f6;color:white}'
|
||||
'p{color:#52606b}}';
|
||||
static const _loaderStyles = '''
|
||||
html,body{height:100%}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#0b0d10;color:#e6e8eb}
|
||||
main{text-align:center;max-width:480px;padding:32px;opacity:0;animation:fade .35s ease-out forwards}
|
||||
@keyframes fade{to{opacity:1}}
|
||||
.spinner{width:56px;height:56px;margin:0 auto 20px;border-radius:50%;border:3px solid rgba(255,255,255,.08);border-top-color:#7aa2f7;animation:spin 1s linear infinite}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
h1{font-size:18px;font-weight:600;margin:0 0 8px;letter-spacing:.2px}
|
||||
p{margin:0;color:#9aa1a8;font-size:14px;line-height:1.5}
|
||||
.dots::after{display:inline-block;width:1.2em;text-align:left;animation:dots 1.4s steps(4,end) infinite;content:""}
|
||||
@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}100%{content:""}}
|
||||
.error h1{color:#f7768e}
|
||||
.actions{margin-top:20px;display:flex;gap:8px;justify-content:center}
|
||||
.btn{padding:10px 16px;border:0;border-radius:10px;cursor:pointer;font:inherit;font-weight:600;background:#7aa2f7;color:#0b0d10}
|
||||
.btn.secondary{background:transparent;color:#9aa1a8;border:1px solid rgba(255,255,255,.12)}
|
||||
.hidden{display:none}
|
||||
@media(prefers-color-scheme:light){body{background:#f5f6f8;color:#1a1d22}.spinner{border-color:rgba(0,0,0,.08);border-top-color:#3b82f6}.btn{background:#3b82f6;color:white}p{color:#52606b}}
|
||||
''';
|
||||
|
||||
// Inline script for the loader shell. Reads window.__TAB_ID__ and
|
||||
// window.__CAPTURE_ID__, long-polls /loader/wait, then either redirects
|
||||
@@ -548,7 +537,7 @@ class CaptureServer {
|
||||
// service has gone away doesn't busy-loop forever — after the cap the
|
||||
// loader gives up and shows the error pane with a Retry button (which
|
||||
// resets the counter via showPending → poll()).
|
||||
static const _loaderScript = r'''
|
||||
static const _loaderScript = '''
|
||||
(function(){
|
||||
var pending=document.getElementById('pending');
|
||||
var error=document.getElementById('error');
|
||||
@@ -606,18 +595,19 @@ class CaptureServer {
|
||||
String _loaderShellBody({required bool initialError}) {
|
||||
final pendingClass = initialError ? 'hidden' : '';
|
||||
final errorClass = initialError ? 'error' : 'error hidden';
|
||||
return '<main id="pending" class="$pendingClass">'
|
||||
'<div class="spinner"></div>'
|
||||
'<h1>Capturing page<span class="dots"></span></h1>'
|
||||
'<p>Saving an offline copy. This usually takes a few seconds.</p>'
|
||||
'</main>'
|
||||
'<main id="error" class="$errorClass">'
|
||||
'<h1>Capture failed</h1>'
|
||||
'<p>The page could not be saved. Check the notification for details.</p>'
|
||||
'<div class="actions">'
|
||||
'<button id="retry" class="btn" type="button">Retry</button>'
|
||||
'</div>'
|
||||
'</main>';
|
||||
return '''
|
||||
<main id="pending" class="$pendingClass">
|
||||
<div class="spinner"></div>
|
||||
<h1>Capturing page<span class="dots"></span></h1>
|
||||
<p>Saving an offline copy. This usually takes a few seconds.</p>
|
||||
</main>
|
||||
<main id="error" class="$errorClass">
|
||||
<h1>Capture failed</h1>
|
||||
<p>The page could not be saved. Check the notification for details.</p>
|
||||
<div class="actions">
|
||||
<button id="retry" class="btn" type="button">Retry</button>
|
||||
</div>
|
||||
</main>''';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:fast_equatable/fast_equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -211,7 +210,7 @@ class _ContentRow extends StatelessWidget {
|
||||
/// instances on every state mutation). Equality is driven instead by scalar
|
||||
/// signatures derived from those collections, which is enough to detect any
|
||||
/// change a single result card cares about.
|
||||
class _FooterState with FastEquatable {
|
||||
class _FooterState {
|
||||
final bool hasOpenSession;
|
||||
final bool isFetching;
|
||||
final bool isFetched;
|
||||
@@ -260,14 +259,26 @@ class _FooterState with FastEquatable {
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get hashParameters => [
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
other is _FooterState &&
|
||||
hasOpenSession == other.hasOpenSession &&
|
||||
isFetching == other.isFetching &&
|
||||
isFetched == other.isFetched &&
|
||||
fetchError == other.fetchError &&
|
||||
_capturingSignature == other._capturingSignature &&
|
||||
_capturesSignature == other._capturesSignature;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
hasOpenSession,
|
||||
isFetching,
|
||||
isFetched,
|
||||
fetchError,
|
||||
_capturingSignature,
|
||||
_capturesSignature,
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
class _FetchFooter extends ConsumerWidget {
|
||||
|
||||
+2
-2
@@ -151,10 +151,10 @@ bool _languageMatchesQuery(String resultLanguage, String? queryTag) {
|
||||
final result = resultLanguage
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.split(RegExp(r'[-_]'))
|
||||
.split(RegExp('[-_]'))
|
||||
.first;
|
||||
|
||||
final query = queryTag.trim().toLowerCase().split(RegExp(r'[-_]')).first;
|
||||
final query = queryTag.trim().toLowerCase().split(RegExp('[-_]')).first;
|
||||
|
||||
if (result.isEmpty || query.isEmpty) return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user