Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6c8c36e
refactor: simplify shared link UI
Lauritz-Tieste Dec 24, 2025
912f314
feat: add delete link functionality in shared link edit page
Lauritz-Tieste Dec 24, 2025
2a9e4aa
refactor: streamline shared link edit page layout and improve code re…
Lauritz-Tieste Dec 24, 2025
969aad1
refactor: update shared link item expiry icon logic for better clarity
Lauritz-Tieste Dec 26, 2025
af17633
feat: enhance shared link expiry options with date selection and presets
Lauritz-Tieste Dec 26, 2025
cf0a9a9
feat: add slug functionality to shared links for custom URLs
Lauritz-Tieste Dec 26, 2025
a166af9
refactor: improve UI elements in shared link edit page for better cla…
Lauritz-Tieste Dec 26, 2025
a768a97
fix: adjust date selection logic to prevent selecting dates in the past
Lauritz-Tieste Dec 26, 2025
ef0da98
feat: add confirmation dialog for deleting shared links
Lauritz-Tieste Dec 26, 2025
7626dc2
fix: convert expiry date to local time for shared links
Lauritz-Tieste Dec 26, 2025
7644a58
fix: enable horizontal scrolling for long text in shared link edit page
Lauritz-Tieste Dec 26, 2025
c4808e0
feat: add sharing functionality for shared link in edit page
Lauritz-Tieste Dec 26, 2025
67a78f9
fix: remove navigating back after deleting shared_link_item
Lauritz-Tieste Dec 26, 2025
5fd43f0
fix: update button style and remove bold font for slug input for cons…
Lauritz-Tieste Dec 26, 2025
46a2be3
fix: remove unnecessary deleteShareLink method
Lauritz-Tieste Dec 26, 2025
6e2ee74
fix: update card shape to fix linting error
Lauritz-Tieste Dec 26, 2025
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
13 changes: 10 additions & 3 deletions mobile/lib/models/shared_link/shared_link.model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class SharedLink {
final String key;
final bool showMetadata;
final SharedLinkSource type;
final String? slug;

const SharedLink({
required this.id,
Expand All @@ -27,6 +28,7 @@ class SharedLink {
required this.key,
required this.showMetadata,
required this.type,
required this.slug,
});

SharedLink copyWith({
Expand All @@ -41,6 +43,7 @@ class SharedLink {
String? key,
bool? showMetadata,
SharedLinkSource? type,
String? slug,
}) {
return SharedLink(
id: id ?? this.id,
Expand All @@ -54,6 +57,7 @@ class SharedLink {
key: key ?? this.key,
showMetadata: showMetadata ?? this.showMetadata,
type: type ?? this.type,
slug: slug ?? this.slug,
);
}

Expand All @@ -66,6 +70,7 @@ class SharedLink {
expiresAt = dto.expiresAt,
key = dto.key,
showMetadata = dto.showMetadata,
slug = dto.slug,
type = dto.type == SharedLinkType.ALBUM ? SharedLinkSource.album : SharedLinkSource.individual,
title = dto.type == SharedLinkType.ALBUM
? dto.album?.albumName.toUpperCase() ?? "UNKNOWN SHARE"
Expand All @@ -78,7 +83,7 @@ class SharedLink {

@override
String toString() =>
'SharedLink(id=$id, title=$title, thumbAssetId=$thumbAssetId, allowDownload=$allowDownload, allowUpload=$allowUpload, description=$description, password=$password, 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, slug=$slug)';

@override
bool operator ==(Object other) =>
Expand All @@ -94,7 +99,8 @@ class SharedLink {
other.expiresAt == expiresAt &&
other.key == key &&
other.showMetadata == showMetadata &&
other.type == type;
other.type == type &&
other.slug == slug;

@override
int get hashCode =>
Expand All @@ -108,5 +114,6 @@ class SharedLink {
expiresAt.hashCode ^
key.hashCode ^
showMetadata.hashCode ^
type.hashCode;
type.hashCode ^
slug.hashCode;
}
93 changes: 31 additions & 62 deletions mobile/lib/pages/library/shared_link/shared_link.page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/models/shared_link/shared_link.model.dart';
import 'package:immich_mobile/providers/shared_link.provider.dart';
import 'package:immich_mobile/widgets/shared_link/shared_link_item.dart';
Expand All @@ -26,71 +25,41 @@ class SharedLinkPage extends HookConsumerWidget {
}, []);

Widget buildNoShares() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
child: const Text(
"shared_link_manage_links",
style: TextStyle(fontSize: 14, color: Colors.grey, fontWeight: FontWeight.bold),
).tr(),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: const Text("you_dont_have_any_shared_links", style: TextStyle(fontSize: 14)).tr(),
),
),
Expanded(
child: Center(
child: Icon(Icons.link_off, size: 100, color: context.themeData.iconTheme.color?.withValues(alpha: 0.5)),
),
),
],
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.link_off, size: 100, color: Theme.of(context).colorScheme.onSurface.withAlpha(128)),
const SizedBox(height: 20),
const Text("you_dont_have_any_shared_links", style: TextStyle(fontSize: 14)).tr(),
],
),
);
}

Widget buildSharesList(List<SharedLink> links) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 16.0, bottom: 30.0),
child: Text(
"shared_link_manage_links",
style: context.textTheme.labelLarge?.copyWith(color: context.textTheme.labelLarge?.color?.withAlpha(200)),
).tr(),
),
Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
// Two column
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisExtent: 180,
),
itemCount: links.length,
itemBuilder: (context, index) {
return SharedLinkItem(links.elementAt(index));
},
);
}

// Single column
return ListView.builder(
itemCount: links.length,
itemBuilder: (context, index) {
return SharedLinkItem(links.elementAt(index));
},
);
},
),
),
],
return LayoutBuilder(
builder: (context, constraints) => constraints.maxWidth > 600
? GridView.builder(
key: const PageStorageKey('shared-links-grid'),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisExtent: 180,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
padding: const EdgeInsets.all(12),
itemCount: links.length,
itemBuilder: (context, index) => SharedLinkItem(links[index]),
)
: ListView.separated(
key: const PageStorageKey('shared-links-list'),
padding: const EdgeInsets.symmetric(vertical: 8),
itemCount: links.length,
itemBuilder: (context, index) => SharedLinkItem(links[index]),
separatorBuilder: (context, index) => const Divider(height: 1),
),
);
}

Expand Down
Loading
Loading