Merge branch 'main' into quickOptions-Refactor
This commit is contained in:
commit
848caedde5
38
.github/workflows/cla.yaml
vendored
Normal file
38
.github/workflows/cla.yaml
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
name: "CLA Assistant"
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_target:
|
||||
types: [opened, closed, synchronize]
|
||||
|
||||
jobs:
|
||||
CLAAssistant:
|
||||
# This job only runs for pull request comments
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "CLA Assistant"
|
||||
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
|
||||
# Beta Release
|
||||
uses: contributor-assistant/github-action@v2.2.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# the below token should have repo scope and must be manually added by you in the repository's secret
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
with:
|
||||
path-to-signatures: "signatures/version1/cla.json"
|
||||
path-to-document: "https://github.com/ente-io/cla/blob/main/CLA.md" # e.g. a CLA or a DCO document
|
||||
# branch should not be protected
|
||||
branch: "main"
|
||||
allowlist: enteio
|
||||
|
||||
# the followings are the optional inputs - If the optional inputs are not given, then default values will be taken
|
||||
#remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository)
|
||||
remote-repository-name: cla
|
||||
#create-file-commit-message: 'For example: Creating file for storing CLA Signatures'
|
||||
#signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo'
|
||||
#custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign'
|
||||
#custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA'
|
||||
#custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.'
|
||||
#lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true)
|
||||
#use-dco-flag: true - If you are using DCO instead of CLA
|
98
CLA.md
Normal file
98
CLA.md
Normal file
|
@ -0,0 +1,98 @@
|
|||
## Contributor License Agreement
|
||||
|
||||
Thank you for your contribution to ente projects.
|
||||
|
||||
This contributor license agreement documents the rights granted by contributors
|
||||
to Ente Technologies, Inc ("ente"). This license is for your protection as a
|
||||
Contributor as well as the protection of ente, its users, and its licensees; you
|
||||
may still license your own Contributions under other terms.
|
||||
|
||||
In exchange for the ability to participate in the ente community and for other
|
||||
good consideration, the receipt of which is hereby acknowledged, you accept and
|
||||
agree to the following terms and conditions for Your present and future
|
||||
Contributions submitted to ente. Except for the license granted herein to ente
|
||||
and recipients of software distributed by ente, You reserve all right, title,
|
||||
and interest in and to Your Contributions.
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"You" (or "Your") shall mean the copyright owner or legal entity authorized
|
||||
by the copyright owner that is making this Agreement with ente. For legal
|
||||
entities, the entity making a Contribution and all other entities that
|
||||
control, are controlled by, or are under common control with that entity are
|
||||
considered to be a single Contributor. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the direction or
|
||||
management of such entity, whether by contract or otherwise, or (ii)
|
||||
ownership of fifty percent (50%) or more of the outstanding shares, or (iii)
|
||||
beneficial ownership of such entity.
|
||||
|
||||
"Contribution" shall mean any original work of authorship or invention,
|
||||
including any modifications or additions to an existing work, that is
|
||||
intentionally submitted by You to ente for inclusion in, or documentation of,
|
||||
any of the products owned or managed by ente (the "Work"). For the purposes
|
||||
of this definition, "submitted" means any form of electronic, verbal, or
|
||||
written communication sent to ente or its representatives, including but not
|
||||
limited to communication on electronic mailing lists, source code control
|
||||
systems, and issue tracking systems that are managed by, or on behalf of,
|
||||
ente for the purpose of discussing and improving the Work, but excluding
|
||||
communication that is conspicuously marked or otherwise designated in writing
|
||||
by You as "Not a Contribution."
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||
Agreement, You hereby grant to ente and to recipients of software distributed
|
||||
by ente a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare derivative works of,
|
||||
publicly display, publicly perform, and distribute Your Contributions and
|
||||
such derivative works.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this
|
||||
Agreement, You hereby grant to ente and to recipients of software distributed
|
||||
by ente a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable by You that
|
||||
are necessarily infringed by Your Contribution(s) alone or by combination of
|
||||
Your Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If any entity institutes patent litigation against You or any
|
||||
other entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that your Contribution, or the Work to which you have contributed,
|
||||
constitutes direct or contributory patent infringement, then any patent
|
||||
licenses granted to that entity under this Agreement for that Contribution or
|
||||
Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. You represent that you are legally entitled to grant the above license. If
|
||||
your employer(s) has rights to intellectual property that you create that
|
||||
includes your Contributions, you represent that you have received permission
|
||||
to make Contributions on behalf of that employer, that your employer has
|
||||
waived such rights for your contributions to ente, or that your employer has
|
||||
executed with ente a separate contributor license agreement substantially
|
||||
similar to this Agreement. If You are a current employee or contractor of
|
||||
ente, then the terms of your existing Employment Agreement or Consulting
|
||||
Services Agreement shall supersede this CLA, and remain in full effect.
|
||||
|
||||
5. You represent that each of Your Contributions is Your original creation (see
|
||||
section 7 for submissions on behalf of others). You represent that Your
|
||||
Contribution submissions include complete details of any third-party license
|
||||
or other restriction (including, but not limited to, related patents and
|
||||
trademarks) of which you are personally aware and which are associated with
|
||||
any part of Your Contributions.
|
||||
|
||||
6. You are not expected to provide support for Your Contributions, except to the
|
||||
extent You desire to provide support. You may provide support for free, for
|
||||
a fee, or not at all. Unless required by applicable law or agreed to in
|
||||
writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
|
||||
without limitation, any warranties or conditions of title, non-infringement,
|
||||
merchantability, or fitness for a particular purpose.
|
||||
|
||||
7. Should You wish to submit work that is not Your original creation, You may
|
||||
submit it to ente separately from any Contribution, identifying the complete
|
||||
details of its source and of any license or other restriction (including, but
|
||||
not limited to, related patents, trademarks, and license agreements) of which
|
||||
you are personally aware, and conspicuously marking the work as "Not a
|
||||
Contribution". Third-party materials licensed pursuant to: [license name(s)
|
||||
here]" (substituting the bracketed text with the appropriate license
|
||||
name(s)).
|
||||
|
||||
8. You agree to notify ente of any facts or circumstances of which you become
|
||||
aware that would make these representations inaccurate in any respect.
|
11
README.md
11
README.md
|
@ -62,8 +62,15 @@ We maintain a public roadmap, that's driven by our community @ [roadmap.ente.io]
|
|||
|
||||
If you like this project, please consider upgrading to a paid subscription.
|
||||
|
||||
If you would like to motivate us to keep building, you can do so by
|
||||
[starring](https://github.com/ente-io/photos-web/stargazers) this project.
|
||||
And [star this repo](https://github.com/ente-io/photos-web/stargazers)!
|
||||
|
||||
<br/>
|
||||
|
||||
## 🌍 Translate
|
||||
|
||||
Create a copy of
|
||||
[src/utils/strings/englishConstants.tsx](src/utils/strings/englishConstants.tsx)
|
||||
and open a PR.
|
||||
|
||||
<br/>
|
||||
|
||||
|
|
|
@ -203,6 +203,7 @@ const PhotoFrame = ({
|
|||
h: window.innerHeight,
|
||||
title: item.pubMagicMetadata?.data.caption,
|
||||
};
|
||||
try {
|
||||
if (galleryContext.thumbs.has(item.id)) {
|
||||
updateFileMsrcProps(
|
||||
filteredItem,
|
||||
|
@ -215,6 +216,9 @@ const PhotoFrame = ({
|
|||
galleryContext.files.get(item.id)
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logError(e, 'PhotoFrame url prefill failed');
|
||||
}
|
||||
return filteredItem;
|
||||
});
|
||||
setFilteredData(filteredData);
|
||||
|
@ -459,12 +463,12 @@ const PhotoFrame = ({
|
|||
) {
|
||||
handleSelect(
|
||||
filteredData[i].id,
|
||||
filteredData[i].ownerID === user.id
|
||||
filteredData[i].ownerID === user?.id
|
||||
)(!checked);
|
||||
}
|
||||
handleSelect(
|
||||
filteredData[index].id,
|
||||
filteredData[index].ownerID === user.id,
|
||||
filteredData[index].ownerID === user?.id,
|
||||
index
|
||||
)(!checked);
|
||||
}
|
||||
|
@ -479,7 +483,10 @@ const PhotoFrame = ({
|
|||
file={item}
|
||||
updateURL={updateURL(index)}
|
||||
onClick={onThumbnailClick(index)}
|
||||
onSelect={handleSelect(item.id, item.ownerID === user.id, index)}
|
||||
selectable={
|
||||
!publicCollectionGalleryContext?.accessedThroughSharedURL
|
||||
}
|
||||
onSelect={handleSelect(item.id, item.ownerID === user?.id, index)}
|
||||
selected={
|
||||
selected.collectionID === activeCollection && selected[item.id]
|
||||
}
|
||||
|
|
|
@ -663,7 +663,11 @@ export function PhotoList({
|
|||
let sum = 0;
|
||||
for (let i = 0; i < listItem.groups.length - 1; i++) {
|
||||
sum = sum + listItem.groups[i];
|
||||
ret.splice(sum, 0, <div />);
|
||||
ret.splice(
|
||||
sum,
|
||||
0,
|
||||
<div key={`${listItem.items[0].id}-gap-${i}`} />
|
||||
);
|
||||
sum += 1;
|
||||
}
|
||||
}
|
||||
|
@ -687,7 +691,7 @@ export function PhotoList({
|
|||
width={width}
|
||||
itemCount={timeStampList.length}
|
||||
itemKey={generateKey}
|
||||
overscanCount={0}
|
||||
overscanCount={3}
|
||||
useIsScrolling>
|
||||
{({ index, style, isScrolling }) => (
|
||||
<ListItem style={style}>
|
||||
|
|
|
@ -20,6 +20,7 @@ interface IProps {
|
|||
file: EnteFile;
|
||||
updateURL: (id: number, url: string) => void;
|
||||
onClick: () => void;
|
||||
selectable: boolean;
|
||||
selected: boolean;
|
||||
onSelect: (checked: boolean) => void;
|
||||
onHover: () => void;
|
||||
|
@ -202,6 +203,7 @@ export default function PreviewCard(props: IProps) {
|
|||
file,
|
||||
onClick,
|
||||
updateURL,
|
||||
selectable,
|
||||
selected,
|
||||
onSelect,
|
||||
selectOnClick,
|
||||
|
@ -220,6 +222,12 @@ export default function PreviewCard(props: IProps) {
|
|||
|
||||
const isMounted = useRef(true);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
isMounted.current = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!file.msrc && !props.showPlaceholder) {
|
||||
const main = async () => {
|
||||
|
@ -253,11 +261,8 @@ export default function PreviewCard(props: IProps) {
|
|||
}
|
||||
};
|
||||
main();
|
||||
return () => {
|
||||
isMounted.current = false;
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
}, [props.showPlaceholder]);
|
||||
|
||||
const handleClick = () => {
|
||||
if (selectOnClick) {
|
||||
|
@ -290,11 +295,12 @@ export default function PreviewCard(props: IProps) {
|
|||
|
||||
return (
|
||||
<Cont
|
||||
id={`thumb-${file.id}-${props.showPlaceholder}`}
|
||||
key={`thumb-${file.id}-${props.showPlaceholder}`}
|
||||
onClick={handleClick}
|
||||
onMouseEnter={handleHover}
|
||||
disabled={!file?.msrc && !imgSrc}
|
||||
{...useLongPress(longPressCallback, 500)}>
|
||||
{...(selectable ? useLongPress(longPressCallback, 500) : {})}>
|
||||
{selectable && (
|
||||
<Check
|
||||
type="checkbox"
|
||||
checked={selected}
|
||||
|
@ -302,7 +308,7 @@ export default function PreviewCard(props: IProps) {
|
|||
$active={isRangeSelectActive && isInsSelectRange}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
|
||||
)}
|
||||
{(file?.msrc || imgSrc) && <img src={file?.msrc || imgSrc} />}
|
||||
{file?.metadata.fileType === 1 && <PlayCircleOutlineOutlinedIcon />}
|
||||
<SelectedOverlay selected={selected} />
|
||||
|
|
|
@ -59,7 +59,7 @@ export const syncFiles = async (
|
|||
let files = await removeDeletedCollectionFiles(collections, localFiles);
|
||||
if (files.length !== localFiles.length) {
|
||||
await setLocalFiles(files);
|
||||
setFiles(files);
|
||||
setFiles(sortFiles(mergeMetadata(files)));
|
||||
}
|
||||
for (const collection of collections) {
|
||||
if (!getToken()) {
|
||||
|
|
|
@ -166,18 +166,13 @@ export function getSelectedFiles(
|
|||
}
|
||||
|
||||
export function sortFiles(files: EnteFile[]) {
|
||||
// sort according to modification time first
|
||||
// then sort according to creation time, maintaining ordering according to modification time for files with creation time
|
||||
return files
|
||||
.sort(
|
||||
(a, b) => b.metadata.modificationTime - a.metadata.modificationTime
|
||||
)
|
||||
.sort((a, b) => {
|
||||
if (a.metadata.modificationTime !== b.metadata.modificationTime) {
|
||||
return 0;
|
||||
} else {
|
||||
return b.metadata.creationTime - a.metadata.creationTime;
|
||||
// sort based on the time of creation time of the file,
|
||||
// for files with same creation time, sort based on the time of last modification
|
||||
return files.sort((a, b) => {
|
||||
if (a.metadata.creationTime === b.metadata.creationTime) {
|
||||
return b.metadata.modificationTime - a.metadata.modificationTime;
|
||||
}
|
||||
return b.metadata.creationTime - a.metadata.creationTime;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { FILE_TYPE } from 'constants/file';
|
||||
import { EnteFile } from 'types/file';
|
||||
import { MergedSourceURL } from 'types/gallery';
|
||||
import { logError } from 'utils/sentry';
|
||||
import constants from 'utils/strings/constants';
|
||||
|
||||
const WAIT_FOR_VIDEO_PLAYBACK = 1 * 1000;
|
||||
|
@ -61,7 +62,11 @@ export function updateFileMsrcProps(file: EnteFile, url: string) {
|
|||
} else if (file.metadata.fileType === FILE_TYPE.IMAGE) {
|
||||
file.src = url;
|
||||
} else {
|
||||
throw Error('Invalid file type');
|
||||
logError(
|
||||
Error(`unknown file type - ${file.metadata.fileType}`),
|
||||
'Unknown file type'
|
||||
);
|
||||
file.src = url;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,15 +82,18 @@ export async function updateFileSrcProps(
|
|||
let originalVideoURL;
|
||||
let convertedImageURL;
|
||||
let convertedVideoURL;
|
||||
let originalURL;
|
||||
if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
|
||||
[originalImageURL, originalVideoURL] = urls.original;
|
||||
[convertedImageURL, convertedVideoURL] = urls.converted;
|
||||
} else if (file.metadata.fileType === FILE_TYPE.VIDEO) {
|
||||
[originalVideoURL] = urls.original;
|
||||
[convertedVideoURL] = urls.converted;
|
||||
} else {
|
||||
} else if (file.metadata.fileType === FILE_TYPE.IMAGE) {
|
||||
[originalImageURL] = urls.original;
|
||||
[convertedImageURL] = urls.converted;
|
||||
} else {
|
||||
[originalURL] = urls.original;
|
||||
}
|
||||
|
||||
const isPlayable =
|
||||
|
@ -141,6 +149,10 @@ export async function updateFileSrcProps(
|
|||
} else if (file.metadata.fileType === FILE_TYPE.IMAGE) {
|
||||
file.src = convertedImageURL;
|
||||
} else {
|
||||
throw Error('Invalid file type');
|
||||
logError(
|
||||
Error(`unknown file type - ${file.metadata.fileType}`),
|
||||
'Unknown file type'
|
||||
);
|
||||
file.src = originalURL;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue