mirror of
https://github.com/immich-app/immich.git
synced 2024-12-23 02:06:15 +02:00
Implemented editable album title (#130)
* Replace static title text with a text edit field * Implement endpoint for updating album info * Implement changing title * Only the owner can change the title
This commit is contained in:
parent
c5c7a134dd
commit
38e0178c81
@ -0,0 +1,53 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class AlbumViewerPageState {
|
||||||
|
final bool isEditAlbum;
|
||||||
|
final String editTitleText;
|
||||||
|
AlbumViewerPageState({
|
||||||
|
required this.isEditAlbum,
|
||||||
|
required this.editTitleText,
|
||||||
|
});
|
||||||
|
|
||||||
|
AlbumViewerPageState copyWith({
|
||||||
|
bool? isEditAlbum,
|
||||||
|
String? editTitleText,
|
||||||
|
}) {
|
||||||
|
return AlbumViewerPageState(
|
||||||
|
isEditAlbum: isEditAlbum ?? this.isEditAlbum,
|
||||||
|
editTitleText: editTitleText ?? this.editTitleText,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
final result = <String, dynamic>{};
|
||||||
|
|
||||||
|
result.addAll({'isEditAlbum': isEditAlbum});
|
||||||
|
result.addAll({'editTitleText': editTitleText});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory AlbumViewerPageState.fromMap(Map<String, dynamic> map) {
|
||||||
|
return AlbumViewerPageState(
|
||||||
|
isEditAlbum: map['isEditAlbum'] ?? false,
|
||||||
|
editTitleText: map['editTitleText'] ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String toJson() => json.encode(toMap());
|
||||||
|
|
||||||
|
factory AlbumViewerPageState.fromJson(String source) => AlbumViewerPageState.fromMap(json.decode(source));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'AlbumViewerPageState(isEditAlbum: $isEditAlbum, editTitleText: $editTitleText)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other is AlbumViewerPageState && other.isEditAlbum == isEditAlbum && other.editTitleText == editTitleText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => isEditAlbum.hashCode ^ editTitleText.hashCode;
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/models/album_viewer_page_state.model.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart';
|
||||||
|
|
||||||
|
class AlbumViewerNotifier extends StateNotifier<AlbumViewerPageState> {
|
||||||
|
AlbumViewerNotifier(this.ref) : super(AlbumViewerPageState(editTitleText: "", isEditAlbum: false));
|
||||||
|
|
||||||
|
final Ref ref;
|
||||||
|
|
||||||
|
void enableEditAlbum() {
|
||||||
|
state = state.copyWith(isEditAlbum: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disableEditAlbum() {
|
||||||
|
state = state.copyWith(isEditAlbum: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEditTitleText(String newTitle) {
|
||||||
|
state = state.copyWith(editTitleText: newTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void remoteEditTitleText() {
|
||||||
|
state = state.copyWith(editTitleText: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetState() {
|
||||||
|
state = state.copyWith(editTitleText: "", isEditAlbum: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> changeAlbumTitle(String albumId, String ownerId, String newAlbumTitle) async {
|
||||||
|
SharedAlbumService service = SharedAlbumService();
|
||||||
|
|
||||||
|
bool isSuccess = await service.changeTitleAlbum(albumId, ownerId, newAlbumTitle);
|
||||||
|
|
||||||
|
if (isSuccess) {
|
||||||
|
state = state.copyWith(editTitleText: "", isEditAlbum: false);
|
||||||
|
ref.read(sharedAlbumProvider.notifier).getAllSharedAlbums();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final albumViewerProvider = StateNotifierProvider<AlbumViewerNotifier, AlbumViewerPageState>((ref) {
|
||||||
|
return AlbumViewerNotifier(ref);
|
||||||
|
});
|
@ -138,4 +138,23 @@ class SharedAlbumService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> changeTitleAlbum(String albumId, String ownerId, String newAlbumTitle) async {
|
||||||
|
try {
|
||||||
|
Response res = await _networkService.patchRequest(url: 'shared/updateInfo', data: {
|
||||||
|
"albumId": albumId,
|
||||||
|
"ownerId": ownerId,
|
||||||
|
"albumName": newAlbumTitle,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res.statusCode != 200) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint("Error deleteAlbum ${e.toString()}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import 'package:fluttertoast/fluttertoast.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
import 'package:immich_mobile/constants/immich_colors.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart';
|
import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/providers/album_viewer.provider.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart';
|
import 'package:immich_mobile/modules/sharing/providers/asset_selection.provider.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart';
|
import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
@ -27,6 +28,8 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isMultiSelectionEnable = ref.watch(assetSelectionProvider).isMultiselectEnable;
|
final isMultiSelectionEnable = ref.watch(assetSelectionProvider).isMultiselectEnable;
|
||||||
final selectedAssetsInAlbum = ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer;
|
final selectedAssetsInAlbum = ref.watch(assetSelectionProvider).selectedAssetsInAlbumViewer;
|
||||||
|
final newAlbumTitle = ref.watch(albumViewerProvider).editTitleText;
|
||||||
|
final isEditAlbum = ref.watch(albumViewerProvider).isEditAlbum;
|
||||||
|
|
||||||
void _onDeleteAlbumPressed(String albumId) async {
|
void _onDeleteAlbumPressed(String albumId) async {
|
||||||
ImmichLoadingOverlayController.appLoader.show();
|
ImmichLoadingOverlayController.appLoader.show();
|
||||||
@ -152,6 +155,24 @@ class AlbumViewerAppbar extends HookConsumerWidget with PreferredSizeWidget {
|
|||||||
icon: const Icon(Icons.close_rounded),
|
icon: const Icon(Icons.close_rounded),
|
||||||
splashRadius: 25,
|
splashRadius: 25,
|
||||||
);
|
);
|
||||||
|
} else if (isEditAlbum) {
|
||||||
|
return IconButton(
|
||||||
|
onPressed: () async {
|
||||||
|
bool isSuccess =
|
||||||
|
await ref.watch(albumViewerProvider.notifier).changeAlbumTitle(albumId, userId, newAlbumTitle);
|
||||||
|
|
||||||
|
if (!isSuccess) {
|
||||||
|
ImmichToast.show(
|
||||||
|
context: context,
|
||||||
|
msg: "Failed to change album title",
|
||||||
|
gravity: ToastGravity.BOTTOM,
|
||||||
|
toastType: ToastType.error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.check_rounded),
|
||||||
|
splashRadius: 25,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
onPressed: () async => await AutoRouter.of(context).pop(),
|
onPressed: () async => await AutoRouter.of(context).pop(),
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/models/shared_album.model.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/providers/album_viewer.provider.dart';
|
||||||
|
|
||||||
|
class AlbumViewerEditableTitle extends HookConsumerWidget {
|
||||||
|
final SharedAlbum albumInfo;
|
||||||
|
final FocusNode titleFocusNode;
|
||||||
|
const AlbumViewerEditableTitle({Key? key, required this.albumInfo, required this.titleFocusNode}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final titleTextEditController = useTextEditingController(text: albumInfo.albumName);
|
||||||
|
|
||||||
|
void onFocusModeChange() {
|
||||||
|
if (!titleFocusNode.hasFocus && titleTextEditController.text.isEmpty) {
|
||||||
|
ref.watch(albumViewerProvider.notifier).setEditTitleText("Untitled");
|
||||||
|
titleTextEditController.text = "Untitled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
titleFocusNode.addListener(onFocusModeChange);
|
||||||
|
return () {
|
||||||
|
titleFocusNode.removeListener(onFocusModeChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return TextField(
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value.isEmpty) {
|
||||||
|
} else {
|
||||||
|
ref.watch(albumViewerProvider.notifier).setEditTitleText(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
focusNode: titleFocusNode,
|
||||||
|
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
controller: titleTextEditController,
|
||||||
|
onTap: () {
|
||||||
|
FocusScope.of(context).requestFocus(titleFocusNode);
|
||||||
|
|
||||||
|
ref.watch(albumViewerProvider.notifier).setEditTitleText(albumInfo.albumName);
|
||||||
|
ref.watch(albumViewerProvider.notifier).enableEditAlbum();
|
||||||
|
|
||||||
|
if (titleTextEditController.text == 'Untitled') {
|
||||||
|
titleTextEditController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||||
|
suffixIcon: titleFocusNode.hasFocus
|
||||||
|
? IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
titleTextEditController.clear();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.cancel_rounded),
|
||||||
|
splashRadius: 10,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.transparent),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.transparent),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
focusColor: Colors.grey[300],
|
||||||
|
fillColor: Colors.grey[200],
|
||||||
|
filled: titleFocusNode.hasFocus,
|
||||||
|
hintText: 'Add a title',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import 'package:immich_mobile/modules/sharing/providers/shared_album.provider.da
|
|||||||
import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart';
|
import 'package:immich_mobile/modules/sharing/services/shared_album.service.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/ui/album_action_outlined_button.dart';
|
import 'package:immich_mobile/modules/sharing/ui/album_action_outlined_button.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/ui/album_viewer_appbar.dart';
|
import 'package:immich_mobile/modules/sharing/ui/album_viewer_appbar.dart';
|
||||||
|
import 'package:immich_mobile/modules/sharing/ui/album_viewer_editable_title.dart';
|
||||||
import 'package:immich_mobile/modules/sharing/ui/album_viewer_thumbnail.dart';
|
import 'package:immich_mobile/modules/sharing/ui/album_viewer_thumbnail.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart';
|
||||||
@ -26,6 +27,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
FocusNode titleFocusNode = useFocusNode();
|
||||||
ScrollController _scrollController = useScrollController();
|
ScrollController _scrollController = useScrollController();
|
||||||
AsyncValue<SharedAlbum> _albumInfo = ref.watch(sharedAlbumDetailProvider(albumId));
|
AsyncValue<SharedAlbum> _albumInfo = ref.watch(sharedAlbumDetailProvider(albumId));
|
||||||
|
|
||||||
@ -83,13 +85,18 @@ class AlbumViewerPage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTitle(String title) {
|
Widget _buildTitle(SharedAlbum albumInfo) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(left: 16.0, top: 16),
|
padding: const EdgeInsets.only(left: 8, right: 8, top: 16),
|
||||||
child: Text(
|
child: userId == albumInfo.ownerId
|
||||||
title,
|
? AlbumViewerEditableTitle(
|
||||||
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
albumInfo: albumInfo,
|
||||||
),
|
titleFocusNode: titleFocusNode,
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
|
child: Text(albumInfo.albumName, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +131,7 @@ class AlbumViewerPage extends HookConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
_buildTitle(albumInfo.albumName),
|
_buildTitle(albumInfo),
|
||||||
_buildAlbumDateRange(albumInfo),
|
_buildAlbumDateRange(albumInfo),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 60,
|
height: 60,
|
||||||
@ -204,31 +211,36 @@ class AlbumViewerPage extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(SharedAlbum albumInfo) {
|
Widget _buildBody(SharedAlbum albumInfo) {
|
||||||
return Stack(children: [
|
return GestureDetector(
|
||||||
DraggableScrollbar.semicircle(
|
onTap: () {
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
titleFocusNode.unfocus();
|
||||||
controller: _scrollController,
|
},
|
||||||
heightScrollThumb: 48.0,
|
child: Stack(children: [
|
||||||
child: CustomScrollView(
|
DraggableScrollbar.semicircle(
|
||||||
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
slivers: [
|
heightScrollThumb: 48.0,
|
||||||
_buildHeader(albumInfo),
|
child: CustomScrollView(
|
||||||
SliverPersistentHeader(
|
controller: _scrollController,
|
||||||
pinned: true,
|
slivers: [
|
||||||
delegate: ImmichSliverPersistentAppBarDelegate(
|
_buildHeader(albumInfo),
|
||||||
minHeight: 50,
|
SliverPersistentHeader(
|
||||||
maxHeight: 50,
|
pinned: true,
|
||||||
child: Container(
|
delegate: ImmichSliverPersistentAppBarDelegate(
|
||||||
color: immichBackgroundColor,
|
minHeight: 50,
|
||||||
child: _buildControlButton(albumInfo),
|
maxHeight: 50,
|
||||||
|
child: Container(
|
||||||
|
color: immichBackgroundColor,
|
||||||
|
child: _buildControlButton(albumInfo),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
_buildImageGrid(albumInfo)
|
||||||
_buildImageGrid(albumInfo)
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
]),
|
||||||
]);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
Headers,
|
Headers,
|
||||||
Delete,
|
Delete,
|
||||||
Logger,
|
Logger,
|
||||||
|
Patch,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard';
|
||||||
import { AssetService } from './asset.service';
|
import { AssetService } from './asset.service';
|
||||||
|
12
server/src/api-v1/sharing/dto/update-shared-album.dto.ts
Normal file
12
server/src/api-v1/sharing/dto/update-shared-album.dto.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { IsNotEmpty } from 'class-validator';
|
||||||
|
|
||||||
|
export class UpdateShareAlbumDto {
|
||||||
|
@IsNotEmpty()
|
||||||
|
albumId: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
albumName: string;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
ownerId: string;
|
||||||
|
}
|
@ -2,10 +2,11 @@ import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards, Validatio
|
|||||||
import { SharingService } from './sharing.service';
|
import { SharingService } from './sharing.service';
|
||||||
import { CreateSharedAlbumDto } from './dto/create-shared-album.dto';
|
import { CreateSharedAlbumDto } from './dto/create-shared-album.dto';
|
||||||
import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../../modules/immich-jwt/guards/jwt-auth.guard';
|
||||||
import { GetAuthUser } from '../../decorators/auth-user.decorator';
|
import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
|
||||||
import { AddAssetsDto } from './dto/add-assets.dto';
|
import { AddAssetsDto } from './dto/add-assets.dto';
|
||||||
import { AddUsersDto } from './dto/add-users.dto';
|
import { AddUsersDto } from './dto/add-users.dto';
|
||||||
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
||||||
|
import { UpdateShareAlbumDto } from './dto/update-shared-album.dto';
|
||||||
|
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@Controller('shared')
|
@Controller('shared')
|
||||||
@ -52,4 +53,9 @@ export class SharingController {
|
|||||||
async leaveAlbum(@GetAuthUser() authUser, @Param('albumId') albumId: string) {
|
async leaveAlbum(@GetAuthUser() authUser, @Param('albumId') albumId: string) {
|
||||||
return await this.sharingService.leaveAlbum(authUser, albumId);
|
return await this.sharingService.leaveAlbum(authUser, albumId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Patch('/updateInfo')
|
||||||
|
async updateAlbumInfo(@GetAuthUser() authUser, @Body(ValidationPipe) updateAlbumInfoDto: UpdateShareAlbumDto) {
|
||||||
|
return await this.sharingService.updateAlbumTitle(authUser, updateAlbumInfoDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import { UserSharedAlbumEntity } from './entities/user-shared-album.entity';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { AddUsersDto } from './dto/add-users.dto';
|
import { AddUsersDto } from './dto/add-users.dto';
|
||||||
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
import { RemoveAssetsDto } from './dto/remove-assets.dto';
|
||||||
|
import { UpdateShareAlbumDto } from './dto/update-shared-album.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SharingService {
|
export class SharingService {
|
||||||
@ -184,4 +185,15 @@ export class SharingService {
|
|||||||
|
|
||||||
return await this.assetSharedAlbumRepository.save([...newRecords]);
|
return await this.assetSharedAlbumRepository.save([...newRecords]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateAlbumTitle(authUser: AuthUserDto, updateShareAlbumDto: UpdateShareAlbumDto) {
|
||||||
|
if (authUser.id != updateShareAlbumDto.ownerId) {
|
||||||
|
throw new BadRequestException('Unauthorized to change album info');
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedAlbum = await this.sharedAlbumRepository.findOne({ where: { id: updateShareAlbumDto.albumId } });
|
||||||
|
sharedAlbum.albumName = updateShareAlbumDto.albumName;
|
||||||
|
|
||||||
|
return await this.sharedAlbumRepository.save(sharedAlbum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user