Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4acd6c29e0 |
@@ -10,7 +10,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/Version-2.0.7-blueviolet?style=for-the-badge" alt="Version 2.0.7" />
|
||||
<img src="https://img.shields.io/badge/Version-2.0.8-blueviolet?style=for-the-badge" alt="Version 2.0.8" />
|
||||
<img src="https://img.shields.io/badge/Flutter-3.47+-02569B?style=for-the-badge&logo=flutter&logoColor=white" alt="Flutter" />
|
||||
<img src="https://img.shields.io/badge/Platform-Android%20%7C%20Linux%20%7C%20Windows-brightgreen?style=for-the-badge" alt="Platforms" />
|
||||
<img src="https://img.shields.io/badge/Gitea-RarDog%2FLunaris-orange?style=for-the-badge&logo=gitea&logoColor=white" alt="Gitea" />
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
## ✨ Основные возможности
|
||||
|
||||
- **🔀 Раздельный мульти-поиск по тегам**: Ввод нескольких тегов через пробел обрабатывает каждый тег независимо, выдавая контент по обоим тегам в одной ленте.
|
||||
- **➕ Локальный оператор `and`**: Для строгого объединения тегов на одном арте достаточно написать между ними `and` (например: `genshin and raiden`).
|
||||
- **🎯 Общие модификаторы в мультипоиске**: При вводе `cat and dog anthro` модификатор `anthro` автоматически применится к обоим тегам (`cat anthro` + `dog anthro`).
|
||||
- **🔀 Раздельный мульти-поиск по тегам через `and`**: Оператор `and` опрашивает серверную базу по каждому тегу независимо и плавно чередует посты обоих тегов в общей ленте.
|
||||
- **🌐 Pawchive в главной ленте**: Глобальная лента недавних постов с Pawchive подключена прямо в общий Feed наравне с Rule34, Gelbooru, e621 и Realbooru.
|
||||
- **🏷️ Интерактивные теги автора**: Быстрая фильтрация по темам с живыми счётчиками постов (`#tag (count)`).
|
||||
- **📢 Анонсы и новости авторов**: Всплывающее окно анонсов автора с датами и текстом обращений к аудитории.
|
||||
@@ -66,9 +66,9 @@
|
||||
|
||||
🔗 **[Gitea Releases (RarDog/Lunaris)](https://gitea.rardogsynapse.online/RarDog/Lunaris/releases)**
|
||||
|
||||
- **Android**: `Lunaris-v2.0.7.apk`
|
||||
- **Linux (x64)**: `Lunaris-v2.0.7-linux-x64.tar.gz`
|
||||
- **Windows**: `LunarisSetup-v2.0.7.exe` / `LunarisPortable-v2.0.7.zip`
|
||||
- **Android**: `Lunaris-v2.0.8.apk`
|
||||
- **Linux (x64)**: `Lunaris-v2.0.8-linux-x64.tar.gz`
|
||||
- **Windows**: `LunarisSetup-v2.0.8.exe` / `LunarisPortable-v2.0.8.zip`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
const appDisplayVersion = '2.0.7';
|
||||
const appBuildNumber = 29;
|
||||
const appDisplayVersion = '2.0.8';
|
||||
const appBuildNumber = 30;
|
||||
const appReleaseChannel = 'Stable';
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
const lunarisChangelog = [
|
||||
LunarisChange(
|
||||
version: '2.0.8',
|
||||
title: 'Shared Context Modifiers for Multi-Tag Search & Clean Tag Filtering',
|
||||
bullets: [
|
||||
'Trailing context modifiers: typing "cat and dog anthro" automatically distributes "anthro" to all "and" branches (cat anthro + dog anthro).',
|
||||
'Optional grouping parenthesis support: e.g. "(cat and dog) anthro".',
|
||||
'Resolved "No posts yet" bug by adapting client post validation to multi-tag stream groups and stripping operator keywords from booru queries.',
|
||||
],
|
||||
),
|
||||
LunarisChange(
|
||||
version: '2.0.7',
|
||||
title: 'Independent Multi-Tag Search Streams, Local "and" Connector, Pawchive in Main Feed & Reverts',
|
||||
|
||||
@@ -164,28 +164,65 @@ class ProviderManager {
|
||||
}
|
||||
|
||||
static List<List<String>> splitTagGroups(List<String> rawTags) {
|
||||
final groups = <List<String>>[];
|
||||
List<String> currentGroup = [];
|
||||
final segments = <List<String>>[];
|
||||
List<String> current = [];
|
||||
|
||||
for (final raw in rawTags) {
|
||||
final token = raw.trim();
|
||||
var token = raw.trim();
|
||||
token = token.replaceAll(RegExp(r'^[\(\)]+|[\(\)]+$'), '').trim();
|
||||
if (token.isEmpty) continue;
|
||||
|
||||
if (token.toLowerCase() == 'and') {
|
||||
if (currentGroup.isNotEmpty) {
|
||||
groups.add(currentGroup);
|
||||
currentGroup = [];
|
||||
if (current.isNotEmpty) {
|
||||
segments.add(current);
|
||||
current = [];
|
||||
}
|
||||
} else {
|
||||
currentGroup.add(token);
|
||||
current.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentGroup.isNotEmpty) {
|
||||
groups.add(currentGroup);
|
||||
if (current.isNotEmpty) {
|
||||
segments.add(current);
|
||||
}
|
||||
|
||||
return groups.isEmpty ? [const []] : groups;
|
||||
if (segments.isEmpty) {
|
||||
return [const []];
|
||||
}
|
||||
|
||||
if (segments.length == 1) {
|
||||
return segments;
|
||||
}
|
||||
|
||||
// Multiple segments separated by 'and'
|
||||
// If the last segment has trailing tags after the branch tag (e.g. 'cat and dog anthro'):
|
||||
// The trailing tags apply as common modifier tags to ALL branches!
|
||||
final lastSegment = segments.last;
|
||||
final prevSegment = segments[segments.length - 2];
|
||||
final branchLen = prevSegment.length.clamp(1, lastSegment.length);
|
||||
|
||||
if (lastSegment.length > branchLen) {
|
||||
final commonTail = lastSegment.sublist(branchLen);
|
||||
final adjustedSegments = <List<String>>[];
|
||||
|
||||
for (int i = 0; i < segments.length; i++) {
|
||||
final seg = i == segments.length - 1
|
||||
? lastSegment
|
||||
: [...segments[i], ...commonTail];
|
||||
|
||||
final seen = <String>{};
|
||||
final deduped = <String>[];
|
||||
for (final t in seg) {
|
||||
if (seen.add(t.toLowerCase())) {
|
||||
deduped.add(t);
|
||||
}
|
||||
}
|
||||
adjustedSegments.add(deduped);
|
||||
}
|
||||
return adjustedSegments;
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
Future<Result<List<Post>>> searchAcrossProviders({
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
name: gel_rule_app
|
||||
description: Local backend/core layer for a Flutter booru browser app.
|
||||
publish_to: "none"
|
||||
version: 2.0.7+29
|
||||
version: 2.0.8+30
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.0 <4.0.0"
|
||||
|
||||
@@ -23,6 +23,39 @@ void main() {
|
||||
]));
|
||||
});
|
||||
|
||||
test('cat and dog anthro applies trailing anthro tag to both branches', () {
|
||||
final groups = ProviderManager.splitTagGroups(['cat', 'and', 'dog', 'anthro']);
|
||||
expect(groups, equals([
|
||||
['cat', 'anthro'],
|
||||
['dog', 'anthro'],
|
||||
]));
|
||||
});
|
||||
|
||||
test('multiple trailing modifiers apply to all and-branches', () {
|
||||
final groups = ProviderManager.splitTagGroups([
|
||||
'cat',
|
||||
'and',
|
||||
'dog',
|
||||
'and',
|
||||
'fox',
|
||||
'anthro',
|
||||
'solo',
|
||||
]);
|
||||
expect(groups, equals([
|
||||
['cat', 'anthro', 'solo'],
|
||||
['dog', 'anthro', 'solo'],
|
||||
['fox', 'anthro', 'solo'],
|
||||
]));
|
||||
});
|
||||
|
||||
test('supports optional parentheses around and branches', () {
|
||||
final groups = ProviderManager.splitTagGroups(['(cat', 'and', 'dog)', 'anthro']);
|
||||
expect(groups, equals([
|
||||
['cat', 'anthro'],
|
||||
['dog', 'anthro'],
|
||||
]));
|
||||
});
|
||||
|
||||
test('multiple multi-tag groups separated by and', () {
|
||||
final groups = ProviderManager.splitTagGroups([
|
||||
'genshin',
|
||||
|
||||
Reference in New Issue
Block a user