Skip to content

Commit

Permalink
Merge branch 'release/v3.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
kitce committed Apr 3, 2022
2 parents b23f009 + 4802837 commit 156864a
Show file tree
Hide file tree
Showing 23 changed files with 193 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .cz.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ commitizen:
changelog_start_rev: v2.0.0
name: cz_conventional_commits
tag_format: v$version
version: 3.3.0
version: 3.4.0
version_files:
- package.json
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
## v3.4.0 (2022-04-04)

### Fix

- **cloud-sync**: issue of empty storage being uploaded to cloud after clearing local data
- **cloud-sync**: unexpected sync action due to uncanceled sync registration
- **editor**: missing dependency `onChange`
- **store**: incorrect data loading logic
- **components**: incorrect toggle button `input` selectors

### Feat

- **editor**: update data set editor layout
- **modal**: update `Modal` responsive layout
- **editor**: trigger `onChange` when removing an item
- **cloud-sync**: trigger sync from cloud main script instead of cloud helper
- **editor**: enhance `filterLabelsGroupsByKeyword`
- **cloud-sync**: update `SycnWithGoogleDrive`

### Refactor

- expose `bootstrap()`

## v3.3.0 (2022-04-03)

### Fix
Expand Down
2 changes: 1 addition & 1 deletion dist/egg.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/libel.meta.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Libel
// @version 3.3.0
// @version 3.4.0
// @author kitce <[email protected]>
// @description Label users on LIHKG
// @homepage https://kitce.github.io/libel
Expand Down
4 changes: 2 additions & 2 deletions dist/libel.user.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "libel",
"namespace": "libel",
"displayName": "Libel",
"version": "3.3.0",
"version": "3.4.0",
"description": "Label users on LIHKG",
"author": "kitce <[email protected]>",
"repository": {
Expand Down
15 changes: 8 additions & 7 deletions src/sync.ts → src/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import store from './store/store';

let unregister: (() => void) | null = null;

const sync = async (auth: gapi.auth2.GoogleAuth) => {
export const sync = async (auth: gapi.auth2.GoogleAuth) => {
const signedIn = auth.isSignedIn.get();
if (signedIn) {
const state = store.getState();
const sync = selectSync(state);
if (!sync.loading) {
if (unregister) {
unregister();
}
await cloud.sync();
unregister = register(auth); // register next sync
// analytics
Expand All @@ -23,16 +26,14 @@ const sync = async (auth: gapi.auth2.GoogleAuth) => {
};

const register = (auth: gapi.auth2.GoogleAuth) => {
const timer = setTimeout(async () => {
await sync(auth);
}, interval);
const id = setTimeout(() => sync(auth), interval);
return () => {
clearTimeout(timer);
clearTimeout(id);
unregister = null;
};
};

(async () => {
export const bootstrap = async () => {
const gapi = await ready();
const auth = gapi.auth2.getAuthInstance();
// bind state change handlers
Expand All @@ -47,4 +48,4 @@ const register = (auth: gapi.auth2.GoogleAuth) => {
});
// initial sync
sync(auth);
})();
};
5 changes: 4 additions & 1 deletion src/components/DataSetEditor/DataSetEditor.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

.data-set-editor {
@apply flex flex-col;
@apply w-80;

&:not(.empty) {
min-width: 28rem;
}
}

.filter-result {
Expand Down
18 changes: 13 additions & 5 deletions src/components/DataSetEditor/DataSetEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface IAutoScrollUserItemIndex {

export interface IProps {
dataSet: IDataSet;
onChange?: (user: string, index: number, label: ILabel) => void;
onChange?: (user: string, index: number, label?: ILabel) => void;
onSubmit: (dataSet: Personal) => void;
}

Expand All @@ -39,6 +39,8 @@ const DataSetEditor: React.FunctionComponent<TProps> = (props) => {
const [autoScrollUserItemIndex, setAutoScrollUserItemIndex] = useState<IAutoScrollUserItemIndex>();
const [error, setError] = useState<string | null>(null);

const empty = labelsGroups.length === 0;

const handleFilterChange: IFilterProps['onChange'] = useCallback((keyword) => {
setKeyword(keyword);
}, []);
Expand All @@ -62,7 +64,7 @@ const DataSetEditor: React.FunctionComponent<TProps> = (props) => {
onChange(user, itemIndex, label);
}
}
}, [labelsGroups, filteredLabelsGroups]);
}, [onChange, labelsGroups, filteredLabelsGroups]);

const handleUserLabelsRemove: IUserLabelsEditorProps['onRemove'] = useCallback((user, index) => {
const [labelsGroupIndex, labelsGroup] = findLabelsGroupByUser(labelsGroups, user);
Expand All @@ -79,8 +81,11 @@ const DataSetEditor: React.FunctionComponent<TProps> = (props) => {
item[2] = !item[2];
});
setLabelsGroups(_labelsGroups);
if (onChange) {
onChange(user, itemIndex);
}
}
}, [labelsGroups, filteredLabelsGroups]);
}, [onChange, labelsGroups, filteredLabelsGroups]);

const handleUserLabelsScroll: IUserLabelsEditorProps['onScroll'] = useCallback(() => {
// allow scrolling to the same label again
Expand Down Expand Up @@ -113,13 +118,16 @@ const DataSetEditor: React.FunctionComponent<TProps> = (props) => {
className={
classNames(
className,
styles.dataSetEditor
styles.dataSetEditor,
{
[styles.empty]: empty
}
)
}
onSubmit={handleSubmit}
>
{
labelsGroups.length > 0 ? (
!empty ? (
<React.Fragment>
<Filter
autoFocus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.body {
@apply flex items-stretch;
@apply max-h-80;
@apply flex;

.data-set-editor {
@apply flex-1;
}
}
1 change: 1 addition & 0 deletions src/components/DataSetEditorModal/DataSetEditorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const DataSetEditorModal: React.FunctionComponent<TProps> = (props) => {
<Modal.Body className={styles.body}>
<DataSetEditor
id={formID}
className={styles.dataSetEditor}
dataSet={dataSet}
onChange={onChange}
onSubmit={onSubmit}
Expand Down
9 changes: 9 additions & 0 deletions src/components/Modal/Modal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@
@apply rounded;
@apply relative;
@apply overflow-hidden;
@apply w-full;
background-color: $color-white01;
box-shadow: 0 4px 8px rgba($color-black, 0.2);
max-height: 80vh;

@include dark-mode() {
background-color: $color-black01;
}

@include mobile-mode() {
@apply max-h-full;
}

@screen md {
@apply w-auto;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
.label {
&,
.hint {
@apply flex items-center;
}

.sync {
@apply flex items-center;

.logo {
@apply w-10;
}

.info {
> .info {
@apply mx-4;
}

.hint {
@apply flex items-center;
@apply mt-2;
@apply text-xs;
@apply opacity-50;

&.info {
@apply items-start;
}

.icon,
span {
@apply opacity-50;
}

.icon {
@apply mr-2;
}
}

.button {
@apply mt-2;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import classNames from 'classnames';
import add from 'date-fns/add';
import formatRelative from 'date-fns/formatRelative';
import { zhHK } from 'date-fns/locale';
import { render } from 'mustache';
import React, { useCallback, useMemo } from 'react';
import logo from '../../../../../assets/logos/google/google-drive.png';
import * as cloud from '../../../../cloud';
import { interval } from '../../../../constants/sync';
import * as TEXTS from '../../../../constants/texts';
import useGoogleAuthorization from '../../../../hooks/useGoogleAuthorization';
import { selectMeta, selectSync } from '../../../../store/selectors';
import { useTypedSelector } from '../../../../store/store';
import lihkgCssClasses from '../../../../stylesheets/variables/lihkg/classes.module.scss';
import * as messages from '../../../../templates/messages';
import Button from '../../../Button/Button';
import ErrorMessage from '../../../ErrorMessage/ErrorMessage';
import Icon from '../../../Icon/Icon';
import { IconName } from '../../../Icon/types';
Expand All @@ -18,15 +26,25 @@ const SyncWithGoogleDrive: React.FunctionComponent = () => {
const meta = useTypedSelector(selectMeta);
const sync = useTypedSelector(selectSync);

const lastSyncedTimeHintText = useMemo(() => {
const infoHints = useMemo(() => {
if (meta.lastSyncedTime) {
const date = new Date(meta.lastSyncedTime);
const now = new Date();
const displayTime = formatRelative(date, now, { locale: zhHK });
return `${TEXTS.CLOUD_SYNC_LABEL_PREFIX_LAST_SYNCED_TIME_HINT} ${displayTime}`;
const lastSyncedTime = formatRelative(meta.lastSyncedTime, now, { locale: zhHK });
const nextSyncTime = formatRelative(add(meta.lastSyncedTime, { seconds: interval / 1000 }), now, { locale: zhHK });
return [
render(messages.sync.lastSyncedTime, { lastSyncedTime }),
render(messages.sync.nextSyncTime, { nextSyncTime })
];
}
}, [meta.lastSyncedTime]);

const handleSyncNowButtonClick: React.MouseEventHandler<HTMLButtonElement> = useCallback((event) => {
event.preventDefault();
if (auth) {
cloud.sync(auth);
}
}, [auth]);

const handleSignIn: React.MouseEventHandler<HTMLAnchorElement> = useCallback(async (event) => {
event.preventDefault();
if (auth) {
Expand All @@ -43,7 +61,7 @@ const SyncWithGoogleDrive: React.FunctionComponent = () => {

return (
<React.Fragment>
<div className={styles.label}>
<div className={styles.sync}>
<img className={styles.logo} src={logo} alt='' />
<div className={styles.info}>
{TEXTS.CLOUD_SYNC_LABEL_GOOGLE_DRIVE}
Expand All @@ -52,30 +70,56 @@ const SyncWithGoogleDrive: React.FunctionComponent = () => {
<React.Fragment>
<small className={styles.hint}>
<Icon className={styles.icon} icon={IconName.Verified} />
{TEXTS.CLOUD_SYNC_LABEL_PREFIX_CONNECTED_ACCOUNT}{' '}
{user.getBasicProfile().getEmail()}
<span>
{TEXTS.CLOUD_SYNC_LABEL_PREFIX_CONNECTED_ACCOUNT}{' '}
{user.getBasicProfile().getEmail()}
</span>
</small>
{
sync.loading ? (
<small className={styles.hint}>
<LoadingSpinner className={styles.icon} />
{TEXTS.CLOUD_SYNC_LABEL_SYNC_IN_PROGRESS}
<span>
{TEXTS.CLOUD_SYNC_LABEL_SYNC_IN_PROGRESS}
</span>
</small>
) : (
<React.Fragment>
{
!!lastSyncedTimeHintText && (
<small className={styles.hint}>
!!infoHints && (
<small className={classNames(styles.hint, styles.info)}>
<Icon className={styles.icon} icon={IconName.CloudUpload} />
{lastSyncedTimeHintText}
<div>
{
infoHints.map((hint, index) => (
<div key={index}>
<span>
{hint}
</span>
</div>
))
}
</div>
</small>
)
}
{
!!sync.error && (
!!sync.error ? (
<ErrorMessage as='small' className={styles.hint}>
{TEXTS.CLOUD_SYNC_ERROR_GENERIC_ERROR}
</ErrorMessage>
) : (
<Button
className={
classNames(
lihkgCssClasses.settingOptionButton,
styles.button
)
}
onClick={handleSyncNowButtonClick}
>
{TEXTS.BUTTON_TEXT_SYNC_NOW}
</Button>
)
}
</React.Fragment>
Expand Down
6 changes: 3 additions & 3 deletions src/components/ToggleButton/ToggleButton.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@apply -translate-y-1/2;
@apply opacity-0;
z-index: 1;

&:not(:disabled) {
@apply cursor-pointer;
}
Expand Down Expand Up @@ -97,7 +97,7 @@
}

&.small {
input input[type='checkbox'],
.input input[type='checkbox'],
.button {
height: 0.6rem;
width: 1.2rem;
Expand All @@ -118,7 +118,7 @@
@apply mr-0 ml-4;
}

input input[type='checkbox'] {
.input input[type='checkbox'] {
@apply -translate-x-full;
}
}
Expand Down
Loading

0 comments on commit 156864a

Please sign in to comment.