new: add postfix to name if it is not unique
This commit is contained in:
@@ -9,6 +9,7 @@ part 'profile_data_source.g.dart';
|
|||||||
abstract interface class ProfileDataSource {
|
abstract interface class ProfileDataSource {
|
||||||
Future<ProfileEntry?> getById(String id);
|
Future<ProfileEntry?> getById(String id);
|
||||||
Future<ProfileEntry?> getByUrl(String url);
|
Future<ProfileEntry?> getByUrl(String url);
|
||||||
|
Future<ProfileEntry?> getByName(String name);
|
||||||
Stream<ProfileEntry?> watchActiveProfile();
|
Stream<ProfileEntry?> watchActiveProfile();
|
||||||
Stream<int> watchProfilesCount();
|
Stream<int> watchProfilesCount();
|
||||||
Stream<List<ProfileEntry>> watchAll({
|
Stream<List<ProfileEntry>> watchAll({
|
||||||
@@ -44,6 +45,13 @@ class ProfileDao extends DatabaseAccessor<AppDatabase>
|
|||||||
..limit(1))
|
..limit(1))
|
||||||
.getSingleOrNull();
|
.getSingleOrNull();
|
||||||
}
|
}
|
||||||
|
@override
|
||||||
|
Future<ProfileEntry?> getByName(String name) async {
|
||||||
|
return (select(profileEntries)
|
||||||
|
..where((tbl) => tbl.name.equals(name))
|
||||||
|
..limit(1))
|
||||||
|
.getSingleOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<ProfileEntry?> watchActiveProfile() {
|
Stream<ProfileEntry?> watchActiveProfile() {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import 'package:uuid/uuid.dart';
|
|||||||
abstract interface class ProfileRepository {
|
abstract interface class ProfileRepository {
|
||||||
TaskEither<ProfileFailure, Unit> init();
|
TaskEither<ProfileFailure, Unit> init();
|
||||||
TaskEither<ProfileFailure, ProfileEntity?> getById(String id);
|
TaskEither<ProfileFailure, ProfileEntity?> getById(String id);
|
||||||
|
Future<ProfileEntity?> getByName(String name);
|
||||||
Stream<Either<ProfileFailure, ProfileEntity?>> watchActiveProfile();
|
Stream<Either<ProfileFailure, ProfileEntity?>> watchActiveProfile();
|
||||||
Stream<Either<ProfileFailure, bool>> watchHasAnyProfile();
|
Stream<Either<ProfileFailure, bool>> watchHasAnyProfile();
|
||||||
|
|
||||||
@@ -97,6 +98,11 @@ class ProfileRepositoryImpl
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ProfileEntity?> getByName(String name) async {
|
||||||
|
return (await profileDataSource.getByName(name))?.toEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<Either<ProfileFailure, ProfileEntity?>> watchActiveProfile() {
|
Stream<Either<ProfileFailure, ProfileEntity?>> watchActiveProfile() {
|
||||||
return profileDataSource
|
return profileDataSource
|
||||||
@@ -361,7 +367,7 @@ class ProfileRepositoryImpl
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final _subInfoHeaders = [
|
static final _subInfoHeaders = [
|
||||||
'profile-title',
|
'profile-title',
|
||||||
'content-disposition',
|
'content-disposition',
|
||||||
'subscription-userinfo',
|
'subscription-userinfo',
|
||||||
@@ -422,9 +428,9 @@ class ProfileRepositoryImpl
|
|||||||
for (final entry in contentHeaders.entries) {
|
for (final entry in contentHeaders.entries) {
|
||||||
if (!headers.keys.contains(entry.key) && entry.value.isNotEmpty) {
|
if (!headers.keys.contains(entry.key) && entry.value.isNotEmpty) {
|
||||||
headers[entry.key] = entry.value;
|
headers[entry.key] = entry.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,9 +68,14 @@ class AddProfile extends _$AddProfile with AppLogger {
|
|||||||
);
|
);
|
||||||
} else if (LinkParser.protocol(rawInput) case (final parsed)?) {
|
} else if (LinkParser.protocol(rawInput) case (final parsed)?) {
|
||||||
loggy.debug("adding profile, content");
|
loggy.debug("adding profile, content");
|
||||||
|
var name = parsed.name;
|
||||||
|
|
||||||
|
while (await _profilesRepo.getByName(name) != null) {
|
||||||
|
name+= '${randomInt(0, 9).run()}';
|
||||||
|
}
|
||||||
task = _profilesRepo.addByContent(
|
task = _profilesRepo.addByContent(
|
||||||
parsed.content,
|
parsed.content,
|
||||||
name: parsed.name,
|
name: name,
|
||||||
markAsActive: markAsActive,
|
markAsActive: markAsActive,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:dartx/dartx.dart';
|
import 'package:dartx/dartx.dart';
|
||||||
|
import 'package:fpdart/fpdart.dart';
|
||||||
import 'package:hiddify/features/profile/data/profile_parser.dart';
|
import 'package:hiddify/features/profile/data/profile_parser.dart';
|
||||||
import 'package:hiddify/features/profile/data/profile_repository.dart';
|
import 'package:hiddify/features/profile/data/profile_repository.dart';
|
||||||
import 'package:hiddify/singbox/model/singbox_proxy_type.dart';
|
import 'package:hiddify/singbox/model/singbox_proxy_type.dart';
|
||||||
@@ -49,30 +50,28 @@ abstract class LinkParser {
|
|||||||
if (uri == null) continue;
|
if (uri == null) continue;
|
||||||
final fragment =
|
final fragment =
|
||||||
uri.hasFragment ? Uri.decodeComponent(uri.fragment) : null;
|
uri.hasFragment ? Uri.decodeComponent(uri.fragment) : null;
|
||||||
if (name != null) {
|
name ??= switch (uri.scheme) {
|
||||||
name = switch (uri.scheme) {
|
'ss' => fragment ?? ProxyType.shadowsocks.label,
|
||||||
'ss' => fragment ?? ProxyType.shadowsocks.label,
|
'ssconf' => fragment ?? ProxyType.shadowsocks.label,
|
||||||
'ssconf' => fragment ?? ProxyType.shadowsocks.label,
|
'vmess' => ProxyType.vmess.label,
|
||||||
'vmess' => ProxyType.vmess.label,
|
'vless' => fragment ?? ProxyType.vless.label,
|
||||||
'vless' => fragment ?? ProxyType.vless.label,
|
'trojan' => fragment ?? ProxyType.trojan.label,
|
||||||
'trojan' => fragment ?? ProxyType.trojan.label,
|
'tuic' => fragment ?? ProxyType.tuic.label,
|
||||||
'tuic' => fragment ?? ProxyType.tuic.label,
|
'hy2' || 'hysteria2' => fragment ?? ProxyType.hysteria2.label,
|
||||||
'hy2' || 'hysteria2' => fragment ?? ProxyType.hysteria2.label,
|
'hy' || 'hysteria' => fragment ?? ProxyType.hysteria.label,
|
||||||
'hy' || 'hysteria' => fragment ?? ProxyType.hysteria.label,
|
'ssh' => fragment ?? ProxyType.ssh.label,
|
||||||
'ssh' => fragment ?? ProxyType.ssh.label,
|
'wg' => fragment ?? ProxyType.wireguard.label,
|
||||||
'wg' => fragment ?? ProxyType.wireguard.label,
|
'warp' => fragment ?? ProxyType.warp.label,
|
||||||
'warp' => fragment ?? ProxyType.warp.label,
|
_ => null,
|
||||||
_ => null,
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final headers = ProfileRepositoryImpl.parseHeadersFromContent(content);
|
final headers = ProfileRepositoryImpl.parseHeadersFromContent(content);
|
||||||
final subinfo = ProfileParser.parse("", headers);
|
final subinfo = ProfileParser.parse("", headers);
|
||||||
|
|
||||||
if (subinfo.name.isNotNullOrEmpty) {
|
if (subinfo.name.isNotNullOrEmpty && subinfo.name != "Remote Profile") {
|
||||||
name = subinfo.name;
|
name = subinfo.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (content: normalContent, name: name ?? ProxyType.unknown.label);
|
return (content: normalContent, name: name ?? ProxyType.unknown.label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user