Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions mobile/lib/models/server_info/server_features.model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,47 @@ class ServerFeatures {
final bool oauthEnabled;
final bool passwordLogin;
final bool ocr;
final bool smartSearch;

const ServerFeatures({
required this.trash,
required this.map,
required this.oauthEnabled,
required this.passwordLogin,
this.ocr = false,
this.smartSearch = false,
});

ServerFeatures copyWith({bool? trash, bool? map, bool? oauthEnabled, bool? passwordLogin, bool? ocr}) {
ServerFeatures copyWith({
bool? trash,
bool? map,
bool? oauthEnabled,
bool? passwordLogin,
bool? ocr,
bool? smartSearch,
}) {
return ServerFeatures(
trash: trash ?? this.trash,
map: map ?? this.map,
oauthEnabled: oauthEnabled ?? this.oauthEnabled,
passwordLogin: passwordLogin ?? this.passwordLogin,
ocr: ocr ?? this.ocr,
smartSearch: smartSearch ?? this.smartSearch,
);
}

@override
String toString() {
return 'ServerFeatures(trash: $trash, map: $map, oauthEnabled: $oauthEnabled, passwordLogin: $passwordLogin, ocr: $ocr)';
return 'ServerFeatures(trash: $trash, map: $map, oauthEnabled: $oauthEnabled, passwordLogin: $passwordLogin, ocr: $ocr, smartSearch: $smartSearch)';
}

ServerFeatures.fromDto(ServerFeaturesDto dto)
: trash = dto.trash,
map = dto.map,
oauthEnabled = dto.oauth,
passwordLogin = dto.passwordLogin,
ocr = dto.ocr;
ocr = dto.ocr,
smartSearch = dto.smartSearch;

@override
bool operator ==(covariant ServerFeatures other) {
Expand All @@ -45,11 +56,17 @@ class ServerFeatures {
other.map == map &&
other.oauthEnabled == oauthEnabled &&
other.passwordLogin == passwordLogin &&
other.ocr == ocr;
other.ocr == ocr &&
other.smartSearch == smartSearch;
}

@override
int get hashCode {
return trash.hashCode ^ map.hashCode ^ oauthEnabled.hashCode ^ passwordLogin.hashCode ^ ocr.hashCode;
return trash.hashCode ^
map.hashCode ^
oauthEnabled.hashCode ^
passwordLogin.hashCode ^
ocr.hashCode ^
smartSearch.hashCode;
}
}
43 changes: 27 additions & 16 deletions mobile/lib/presentation/pages/search/drift_search.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:immich_mobile/presentation/widgets/timeline/timeline.widget.dart
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
import 'package:immich_mobile/providers/infrastructure/user_metadata.provider.dart';
import 'package:immich_mobile/providers/search/search_input_focus.provider.dart';
import 'package:immich_mobile/providers/server_info.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/widgets/common/feature_check.dart';
import 'package:immich_mobile/widgets/common/search_field.dart';
Expand All @@ -39,8 +40,15 @@ class DriftSearchPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final textSearchType = useState<TextSearchType>(TextSearchType.context);
final searchHintText = useState<String>('sunrise_on_the_beach'.t(context: context));
final serverFeatures = ref.watch(serverInfoProvider.select((v) => v.serverFeatures));
final textSearchType = useState<TextSearchType>(
serverFeatures.smartSearch ? TextSearchType.context : TextSearchType.filename,
);
final searchHintText = useState<String>(
serverFeatures.smartSearch
? 'sunrise_on_the_beach'.t(context: context)
: 'file_name_or_extension'.t(context: context),
);
final textSearchController = useTextEditingController();
final preFilter = ref.watch(searchPreFilterProvider);
final filter = useState<SearchFilter>(
Expand Down Expand Up @@ -518,23 +526,26 @@ class DriftSearchPage extends HookConsumerWidget {
);
},
menuChildren: [
MenuItemButton(
child: ListTile(
leading: const Icon(Icons.image_search_rounded),
title: Text(
'search_by_context'.t(context: context),
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
color: textSearchType.value == TextSearchType.context ? context.colorScheme.primary : null,
FeatureCheck(
feature: (features) => features.smartSearch,
child: MenuItemButton(
child: ListTile(
leading: const Icon(Icons.image_search_rounded),
title: Text(
'search_by_context'.t(context: context),
style: context.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
color: textSearchType.value == TextSearchType.context ? context.colorScheme.primary : null,
),
),
selectedColor: context.colorScheme.primary,
selected: textSearchType.value == TextSearchType.context,
),
selectedColor: context.colorScheme.primary,
selected: textSearchType.value == TextSearchType.context,
onPressed: () {
textSearchType.value = TextSearchType.context;
searchHintText.value = 'sunrise_on_the_beach'.t(context: context);
},
),
onPressed: () {
textSearchType.value = TextSearchType.context;
searchHintText.value = 'sunrise_on_the_beach'.t(context: context);
},
),
MenuItemButton(
child: ListTile(
Expand Down
Loading