Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Added remove photos from album feature #98

Merged
merged 4 commits into from
Dec 26, 2021
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
1 change: 1 addition & 0 deletions frontend/public/404.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 11 additions & 3 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SideNav from './components/SideNav';
import { DrawerAppContent } from '@rmwc/drawer';
import '@rmwc/theme/styles';
import './App.scss';
export const CreateAlbumContext = createContext();
export const AlbumsContext = createContext();

const link = createUploadLink({ uri: process.env.REACT_APP_API_URL });
const client = new ApolloClient({
Expand All @@ -21,11 +21,19 @@ const App = () => {
const toggle = () => setOpen(!open);

const [imageList, setImageList] = useState([]);
const [removeImageList, setRemoveImageList] = useState([]);
const [addImageList, setAddImageList] = useState([]);

return (
<ApolloProvider client={client}>
<div className="App">
<CreateAlbumContext.Provider value={{ imageList, setImageList }}>
<AlbumsContext.Provider
value={{
createAlbum: [imageList, setImageList],
removePhotos: [removeImageList, setRemoveImageList],
addPhotos: [addImageList, setAddImageList],
}}
>
<ThemeProvider
options={{
primary: '#812ce5',
Expand All @@ -42,7 +50,7 @@ const App = () => {
</DrawerAppContent>
</BrowserRouter>
</ThemeProvider>
</CreateAlbumContext.Provider>
</AlbumsContext.Provider>
</div>
</ApolloProvider>
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/Content.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Photos,
Search,
Upcoming,
PageNotFound,
Favourites,
Trash,
Albums,
Expand All @@ -28,12 +29,14 @@ const Content = () => {
<Route exact path="/favourites" component={Favourites} />
<Route exact path="/albums" component={Albums} />
<Route exact path="/album/:id" component={Album} />
<Route exact path="/album/:id/add" component={Photos} />
<Route path="/search" component={Search} />
{/* static */}
<Route exact path="/sharing" component={Upcoming} />
<Route exact path="/utilities" component={Upcoming} />
<Route exact path="/archive" component={Upcoming} />
<Route exact path="/trash" component={Trash} />
<Route component={PageNotFound} />
</Switch>
</>
);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/DeleteAlbumDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { gql, useMutation } from '@apollo/client';
import { CircularProgress } from '@rmwc/circular-progress';
import { Snackbar } from '@rmwc/snackbar';
import { Dialog, DialogTitle, DialogActions, DialogButton } from '@rmwc/dialog';
import '@rmwc/dialog/styles';

Expand All @@ -27,6 +28,7 @@ const DeleteAlbumDialog = ({ open, setOpen, albumName, albumId }) => {
setTimeout(() => {
history.push('/albums');
}, 2000);
return <Snackbar open={true} message={'Album has been deleted'} />;
}

return (
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/header/CreateAlbum.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const CreateAlbum = ({ disabled, imageList }) => {

if (data && data.createAlbum) {
setTimeout(() => {
history.push('/albums');
history.push(`/album/${data.createAlbum}`);
history.go(0);
});
return <Snackbar open={true} message={'New album created'} />;
Expand Down
11 changes: 9 additions & 2 deletions frontend/src/components/header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ import { NavLink } from 'react-router-dom';
import SearchBar from './SearchBar';
import Upload from './Upload';
import CreateAlbum from './CreateAlbum';
import { CreateAlbumContext } from '../../App';
import UpdateAlbum from './UpdateAlbum';
import { AlbumsContext } from '../../App';

const Header = ({ toggleSideNav }) => {
const { imageList } = useContext(CreateAlbumContext);
const { createAlbum, removePhotos } = useContext(AlbumsContext);
const [removeImageList] = removePhotos;
const [imageList] = createAlbum;

return (
<div>
Expand All @@ -34,6 +37,10 @@ const Header = ({ toggleSideNav }) => {
<SearchBar />
</TopAppBarSection>
<TopAppBarSection alignEnd>
<UpdateAlbum
removeImageList={removeImageList}
disabled={removeImageList.length === 0}
/>
<CreateAlbum
imageList={imageList}
disabled={imageList.length === 0}
Expand Down
107 changes: 107 additions & 0 deletions frontend/src/components/header/UpdateAlbum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { gql, useMutation } from '@apollo/client';
import { TopAppBarActionItem } from '@rmwc/top-app-bar';
import { Snackbar } from '@rmwc/snackbar';
import { Button } from '@rmwc/button';
import { Error } from '..';

const UPDATE_ALBUM = gql`
mutation updateAlbumMediaItems(
$id: String!
$type: String!
$mediaItems: [String!]!
) {
updateAlbumMediaItems(id: $id, type: $type, mediaItems: $mediaItems)
}
`;

var pageURL = window.location.href;
var albumId = pageURL.split('/');

const UpdateAlbum = ({ disabled, removeImageList, addImageList }) => {
const history = useHistory();
const [updateAlbum, { data, error, loading }] = useMutation(UPDATE_ALBUM);
const handleUpdate = (updatedList, type) => {
type === 'add'
? updateAlbum({
variables: {
id: String(albumId[albumId.length - 2]),
type: type,
mediaItems: updatedList,
},
})
: updateAlbum({
variables: {
id: String(albumId[albumId.length - 1]),
type: type,
mediaItems: updatedList,
},
});
};

if (loading)
return (
<Snackbar
open={true}
message={
removeImageList
? 'Removing photos from album...'
: 'Adding photos to album...'
}
/>
);

if (data && data.updateAlbumMediaItems) {
setTimeout(() => {
if (removeImageList) {
history.go(0);
} else {
history.push(`/album/${albumId[albumId.length - 2]}`);
}
});
return (
<Snackbar
open={true}
message={
removeImageList
? 'Photo has been deleted'
: 'Photo has been added to album'
}
/>
);
}

if (error) return <Error />;

return (
<>
{removeImageList ? (
<TopAppBarActionItem
icon={disabled ? '' : 'remove_circle_outline'}
style={{ color: 'red' }}
disabled={disabled ? true : false}
onClick={() => handleUpdate(removeImageList, 'remove')}
/>
) : (
<Button
icon="add"
label={`Add (${addImageList.length})`}
unelevated
style={{ color: '#fff' }}
disabled={disabled ? true : false}
onClick={() => handleUpdate(addImageList, 'add')}
/>
)}
</>
);
};

UpdateAlbum.propTypes = {
disabled: PropTypes.bool,
removeImageList: PropTypes.array,
addImageList: PropTypes.array,
};

export default UpdateAlbum;
117 changes: 105 additions & 12 deletions frontend/src/pages/Album.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import React, { useState, useContext } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { useHistory } from 'react-router-dom';
import { useParams } from 'react-router-dom';
Expand All @@ -14,6 +15,7 @@ import { Button } from '@rmwc/button';
import { Grid, GridCell } from '@rmwc/grid';
import '@rmwc/grid/styles';
import { Loading, Error, DeleteAlbumDialog, EditAlbum } from '../components';
import { AlbumsContext } from '../App';

const GET_ALBUM = gql`
query getAlbum($id: String!) {
Expand All @@ -33,14 +35,64 @@ const GET_ALBUM = gql`
}
`;

const Album = () => {
const AlbumPhoto = ({
imageUrl,
imageId,
removeImageList,
setRemoveImageList,
}) => {
let history = useHistory();
Comment on lines +38 to 44
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this component or we can re-use similar existing one by handling props and null values?


const [isSelected, setIsSelected] = useState(false);

const onSelect = () => {
if (removeImageList.includes(imageId)) {
setRemoveImageList((arr) =>
arr.filter((_imageId) => _imageId !== imageId)
);
setIsSelected(!isSelected);
} else {
setRemoveImageList((arr) => [...arr, imageId]);
setIsSelected(!isSelected);
}
};
return (
<div className="select-photo">
<Icon
icon={{
icon: 'check_circle',
size: 'medium',
}}
className="select-icon"
style={{
color: isSelected ? '#4800b2' : '#ffffff',
cursor: 'pointer',
zIndex: '1',
}}
onClick={onSelect}
/>
<ImageListImageAspectContainer>
<ImageListImage
src={`${imageUrl}?width=200&height=200`}
style={{ cursor: 'pointer', borderRadius: '4px' }}
onClick={() => history.push(`/photo/${imageId}`)}
/>
</ImageListImageAspectContainer>
</div>
);
};

const Album = () => {
let { id } = useParams();
let history = useHistory();
const { error, loading, data } = useQuery(GET_ALBUM, {
variables: { id },
fetchPolicy: 'no-cache',
});

const { removePhotos } = useContext(AlbumsContext);
const [removeImageList, setRemoveImageList] = removePhotos;

if (error) return <Error />;

const styleFav = {
Expand Down Expand Up @@ -84,6 +136,13 @@ const Album = () => {
albumName={data.album.name}
albumId={data.album.id}
/>
&nbsp;&nbsp;&nbsp;
<Button
icon="add"
label="Add photos"
outlined
onClick={() => history.push(`/album/${id}/add`)}
/>
</div>
<span style={{ color: '#424242' }}>
{moment(data.album.createdAt).format('MMMM D, YYYY')}
Expand All @@ -95,13 +154,12 @@ const Album = () => {
<ImageList>
{data.album.mediaItems.nodes.map((img) => (
<ImageListItem key={img.id} style={styleFav}>
<ImageListImageAspectContainer>
<ImageListImage
src={`${img.imageUrl}?width=200&height=200`}
style={{ cursor: 'pointer', borderRadius: '4px' }}
onClick={() => history.push(`/photo/${img.id}`)}
/>
</ImageListImageAspectContainer>
<AlbumPhoto
imageUrl={img.imageUrl}
imageId={img.id}
removeImageList={removeImageList}
setRemoveImageList={setRemoveImageList}
/>
</ImageListItem>
))}
</ImageList>
Expand All @@ -112,9 +170,37 @@ const Album = () => {
<>
<Grid>
<GridCell span={12}>
{data.album.name}
&nbsp;&nbsp;&nbsp;
<Button icon="add" label="Add photos" outlined />
<div
style={{
display: 'flex',
justifyContent: 'start',
alignItems: 'center',
}}
>
<EditAlbum
albumName={data.album.name}
albumId={data.album.id}
/>
&nbsp;&nbsp;&nbsp;
<Icon
onClick={() => setOpen(true)}
style={{ cursor: 'pointer', color: '#424242' }}
icon={{ icon: 'delete', size: 'small' }}
/>
<DeleteAlbumDialog
open={open}
setOpen={setOpen}
albumName={data.album.name}
albumId={data.album.id}
/>
&nbsp;&nbsp;&nbsp;
<Button
icon="add"
label="Add photos"
outlined
onClick={() => history.push(`/album/${id}/add`)}
/>
</div>
</GridCell>
</Grid>
</>
Expand All @@ -125,4 +211,11 @@ const Album = () => {
);
};

AlbumPhoto.propTypes = {
imageUrl: PropTypes.string,
imageId: PropTypes.string,
removeImageList: PropTypes.array,
setRemoveImageList: PropTypes.func,
};

export default Album;
Loading