feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
/// A mention autocomplete candidate. Mirrors the desktop's
|
||||
/// `MentionCandidateForRanking` (desktop/src/features/messages/lib/mentionRanking.ts).
|
||||
@immutable
|
||||
class MentionCandidate {
|
||||
final String pubkey;
|
||||
final String? displayName;
|
||||
final String? secondaryLabel;
|
||||
final String? avatarUrl;
|
||||
final bool isAgent;
|
||||
final bool isMember;
|
||||
final String? role;
|
||||
final String? ownerPubkey;
|
||||
|
||||
const MentionCandidate({
|
||||
required this.pubkey,
|
||||
this.displayName,
|
||||
this.secondaryLabel,
|
||||
this.avatarUrl,
|
||||
this.isAgent = false,
|
||||
this.isMember = false,
|
||||
this.role,
|
||||
this.ownerPubkey,
|
||||
});
|
||||
|
||||
String get label {
|
||||
final name = displayName?.trim();
|
||||
if (name != null && name.isNotEmpty) return name;
|
||||
return pubkey.length >= 8 ? pubkey.substring(0, 8) : pubkey;
|
||||
}
|
||||
}
|
||||
|
||||
/// Group rank: channel members, then people, then other agents.
|
||||
/// Mirrors desktop's `getMentionCandidateGroupRank` (personas are a
|
||||
/// desktop-only concept; their slot between members and people is unused
|
||||
/// here so numbering stays aligned).
|
||||
int _groupRank(MentionCandidate candidate) {
|
||||
if (candidate.isMember) return 0;
|
||||
if (!candidate.isAgent) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
/// Match-quality score for one label. Lower is better; null means no match.
|
||||
/// Mirrors desktop's `scoreMentionCandidateLabel`.
|
||||
int? _scoreLabel(String label, String lowerQuery) {
|
||||
final lower = label.toLowerCase();
|
||||
if (lower == lowerQuery) return 0;
|
||||
if (lower.startsWith(lowerQuery)) return 1;
|
||||
|
||||
final words = lower.split(RegExp(r'[\s\-_]+')).where((w) => w.isNotEmpty);
|
||||
if (words.any((word) => word == lowerQuery)) return 2;
|
||||
if (words.any((word) => word.startsWith(lowerQuery))) return 3;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Rank candidates for a mention query. Mirrors desktop's
|
||||
/// `rankMentionCandidates`: sort by group, then match quality, then the
|
||||
/// stable original order.
|
||||
List<MentionCandidate> rankMentionCandidates(
|
||||
List<MentionCandidate> candidates,
|
||||
String query,
|
||||
) {
|
||||
final lowerQuery = query.toLowerCase();
|
||||
|
||||
final ranked = <(MentionCandidate, int, int, int)>[];
|
||||
for (var order = 0; order < candidates.length; order++) {
|
||||
final candidate = candidates[order];
|
||||
|
||||
final labelScores = [candidate.displayName, candidate.secondaryLabel].map((
|
||||
value,
|
||||
) {
|
||||
final trimmed = value?.trim();
|
||||
if (trimmed == null || trimmed.isEmpty) return null;
|
||||
return _scoreLabel(trimmed, lowerQuery);
|
||||
}).whereType<int>();
|
||||
int? score = labelScores.isEmpty
|
||||
? null
|
||||
: labelScores.reduce((a, b) => a < b ? a : b);
|
||||
|
||||
if (score == null) {
|
||||
final pubkeyLower = candidate.pubkey.toLowerCase();
|
||||
if (pubkeyLower.startsWith(lowerQuery)) {
|
||||
score = 4;
|
||||
} else if (pubkeyLower.contains(lowerQuery)) {
|
||||
score = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (score == null) continue;
|
||||
ranked.add((candidate, _groupRank(candidate), score, order));
|
||||
}
|
||||
|
||||
ranked.sort((a, b) {
|
||||
final group = a.$2.compareTo(b.$2);
|
||||
if (group != 0) return group;
|
||||
final score = a.$3.compareTo(b.$3);
|
||||
if (score != 0) return score;
|
||||
return a.$4.compareTo(b.$4);
|
||||
});
|
||||
|
||||
return [for (final item in ranked) item.$1];
|
||||
}
|
||||
Reference in New Issue
Block a user