mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(server,web,mobile): Add optional password option for share links. (#4655)
* feat(server,web,mobile): Add optional password option for share links. Signed-off-by: jarvis2f <137974272+jarvis2f@users.noreply.github.com> * feat(server,web): Update shared-link.controller and page.svelte for improved cookie handling and metadata updates. Signed-off-by: jarvis2f <137974272+jarvis2f@users.noreply.github.com> --------- Signed-off-by: jarvis2f <137974272+jarvis2f@users.noreply.github.com>
This commit is contained in:
parent
b34cbd881a
commit
8a6889529c
33 changed files with 556 additions and 41 deletions
|
|
@ -9,6 +9,7 @@ class SharedLink {
|
|||
final bool allowUpload;
|
||||
final String? thumbAssetId;
|
||||
final String? description;
|
||||
final String? password;
|
||||
final DateTime? expiresAt;
|
||||
final String key;
|
||||
final bool showMetadata;
|
||||
|
|
@ -21,6 +22,7 @@ class SharedLink {
|
|||
required this.allowUpload,
|
||||
required this.thumbAssetId,
|
||||
required this.description,
|
||||
required this.password,
|
||||
required this.expiresAt,
|
||||
required this.key,
|
||||
required this.showMetadata,
|
||||
|
|
@ -34,6 +36,7 @@ class SharedLink {
|
|||
bool? allowDownload,
|
||||
bool? allowUpload,
|
||||
String? description,
|
||||
String? password,
|
||||
DateTime? expiresAt,
|
||||
String? key,
|
||||
bool? showMetadata,
|
||||
|
|
@ -46,6 +49,7 @@ class SharedLink {
|
|||
allowDownload: allowDownload ?? this.allowDownload,
|
||||
allowUpload: allowUpload ?? this.allowUpload,
|
||||
description: description ?? this.description,
|
||||
password: password ?? this.password,
|
||||
expiresAt: expiresAt ?? this.expiresAt,
|
||||
key: key ?? this.key,
|
||||
showMetadata: showMetadata ?? this.showMetadata,
|
||||
|
|
@ -58,6 +62,7 @@ class SharedLink {
|
|||
allowDownload = dto.allowDownload,
|
||||
allowUpload = dto.allowUpload,
|
||||
description = dto.description,
|
||||
password = dto.password,
|
||||
expiresAt = dto.expiresAt,
|
||||
key = dto.key,
|
||||
showMetadata = dto.showMetadata,
|
||||
|
|
@ -75,7 +80,7 @@ class SharedLink {
|
|||
|
||||
@override
|
||||
String toString() =>
|
||||
'SharedLink(id=$id, title=$title, thumbAssetId=$thumbAssetId, allowDownload=$allowDownload, allowUpload=$allowUpload, description=$description, expiresAt=$expiresAt, key=$key, showMetadata=$showMetadata, type=$type)';
|
||||
'SharedLink(id=$id, title=$title, thumbAssetId=$thumbAssetId, allowDownload=$allowDownload, allowUpload=$allowUpload, description=$description, password=$password, expiresAt=$expiresAt, key=$key, showMetadata=$showMetadata, type=$type)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
|
|
@ -87,6 +92,7 @@ class SharedLink {
|
|||
other.allowDownload == allowDownload &&
|
||||
other.allowUpload == allowUpload &&
|
||||
other.description == description &&
|
||||
other.password == password &&
|
||||
other.expiresAt == expiresAt &&
|
||||
other.key == key &&
|
||||
other.showMetadata == showMetadata &&
|
||||
|
|
@ -100,6 +106,7 @@ class SharedLink {
|
|||
allowDownload.hashCode ^
|
||||
allowUpload.hashCode ^
|
||||
description.hashCode ^
|
||||
password.hashCode ^
|
||||
expiresAt.hashCode ^
|
||||
key.hashCode ^
|
||||
showMetadata.hashCode ^
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class SharedLinkService {
|
|||
required bool allowDownload,
|
||||
required bool allowUpload,
|
||||
String? description,
|
||||
String? password,
|
||||
String? albumId,
|
||||
List<String>? assetIds,
|
||||
DateTime? expiresAt,
|
||||
|
|
@ -57,6 +58,7 @@ class SharedLinkService {
|
|||
allowUpload: allowUpload,
|
||||
expiresAt: expiresAt,
|
||||
description: description,
|
||||
password: password,
|
||||
);
|
||||
} else if (assetIds != null) {
|
||||
dto = SharedLinkCreateDto(
|
||||
|
|
@ -66,6 +68,7 @@ class SharedLinkService {
|
|||
allowUpload: allowUpload,
|
||||
expiresAt: expiresAt,
|
||||
description: description,
|
||||
password: password,
|
||||
assetIds: assetIds,
|
||||
);
|
||||
}
|
||||
|
|
@ -90,6 +93,7 @@ class SharedLinkService {
|
|||
required bool? allowUpload,
|
||||
bool? changeExpiry = false,
|
||||
String? description,
|
||||
String? password,
|
||||
DateTime? expiresAt,
|
||||
}) async {
|
||||
try {
|
||||
|
|
@ -101,6 +105,7 @@ class SharedLinkService {
|
|||
allowUpload: allowUpload,
|
||||
expiresAt: expiresAt,
|
||||
description: description,
|
||||
password: password,
|
||||
changeExpiryTime: changeExpiry,
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
final descriptionController =
|
||||
useTextEditingController(text: existingLink?.description ?? "");
|
||||
final descriptionFocusNode = useFocusNode();
|
||||
final passwordController =
|
||||
useTextEditingController(text: existingLink?.password ?? "");
|
||||
final showMetadata = useState(existingLink?.showMetadata ?? true);
|
||||
final allowDownload = useState(existingLink?.allowDownload ?? true);
|
||||
final allowUpload = useState(existingLink?.allowUpload ?? false);
|
||||
|
|
@ -113,6 +115,31 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget buildPasswordField() {
|
||||
return TextField(
|
||||
controller: passwordController,
|
||||
enabled: newShareLink.value.isEmpty,
|
||||
autofocus: false,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'shared_link_edit_password'.tr(),
|
||||
labelStyle: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: themeData.primaryColor,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||
border: const OutlineInputBorder(),
|
||||
hintText: 'shared_link_edit_password_hint'.tr(),
|
||||
hintStyle: const TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
),
|
||||
disabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.grey.withOpacity(0.5)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildShowMetaButton() {
|
||||
return SwitchListTile.adaptive(
|
||||
value: showMetadata.value,
|
||||
|
|
@ -229,7 +256,9 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
void copyLinkToClipboard() {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: newShareLink.value,
|
||||
text: passwordController.text.isEmpty
|
||||
? newShareLink.value
|
||||
: "Link: ${newShareLink.value}\nPassword: ${passwordController.text}",
|
||||
),
|
||||
).then((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
|
|
@ -302,6 +331,9 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
description: descriptionController.text.isEmpty
|
||||
? null
|
||||
: descriptionController.text,
|
||||
password: passwordController.text.isEmpty
|
||||
? null
|
||||
: passwordController.text,
|
||||
expiresAt: expiryAfter.value == 0 ? null : calculateExpiry(),
|
||||
);
|
||||
ref.invalidate(sharedLinksStateProvider);
|
||||
|
|
@ -324,6 +356,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
bool? upload;
|
||||
bool? meta;
|
||||
String? desc;
|
||||
String? password;
|
||||
DateTime? expiry;
|
||||
bool? changeExpiry;
|
||||
|
||||
|
|
@ -343,6 +376,10 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
desc = descriptionController.text;
|
||||
}
|
||||
|
||||
if (passwordController.text != existingLink!.password) {
|
||||
password = passwordController.text;
|
||||
}
|
||||
|
||||
if (editExpiry.value) {
|
||||
expiry = expiryAfter.value == 0 ? null : calculateExpiry();
|
||||
changeExpiry = true;
|
||||
|
|
@ -354,6 +391,7 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
allowDownload: download,
|
||||
allowUpload: upload,
|
||||
description: desc,
|
||||
password: password,
|
||||
expiresAt: expiry,
|
||||
changeExpiry: changeExpiry,
|
||||
);
|
||||
|
|
@ -385,6 +423,10 @@ class SharedLinkEditPage extends HookConsumerWidget {
|
|||
padding: const EdgeInsets.all(padding),
|
||||
child: buildDescriptionField(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(padding),
|
||||
child: buildPasswordField(),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: padding,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue