mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-30 13:20:45 +08:00
+20
-3
@@ -6,13 +6,11 @@ export const card = style({
|
||||
borderRadius: 8,
|
||||
background: cssVarV2.layer.background.primary,
|
||||
border: `1px solid ${cssVarV2.layer.insideBorder.border}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 4,
|
||||
});
|
||||
export const divider = style({
|
||||
height: 8,
|
||||
display: 'flex',
|
||||
margin: '4px 0',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
':before': {
|
||||
@@ -26,6 +24,7 @@ export const header = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
padding: '7px 0',
|
||||
});
|
||||
export const colorPickerTrigger = style({
|
||||
width: 24,
|
||||
@@ -82,3 +81,21 @@ export const name = style({
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
});
|
||||
|
||||
export const allDayEventsContainer = style({
|
||||
overflow: 'hidden',
|
||||
display: 'grid',
|
||||
gridTemplateRows: '1fr',
|
||||
transition:
|
||||
'grid-template-rows 0.4s cubic-bezier(.07,.83,.46,1), opacity 0.4s ease',
|
||||
selectors: {
|
||||
'&[data-collapsed="true"]': {
|
||||
gridTemplateRows: '0fr',
|
||||
opacity: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const allDayEventsContent = style({
|
||||
overflow: 'hidden',
|
||||
});
|
||||
|
||||
+64
-9
@@ -1,4 +1,4 @@
|
||||
import { Button, Menu } from '@affine/component';
|
||||
import { Button, Menu, useConfirmModal } from '@affine/component';
|
||||
import {
|
||||
type CalendarSubscription,
|
||||
IntegrationService,
|
||||
@@ -7,6 +7,7 @@ import { useI18n } from '@affine/i18n';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { IntegrationSettingToggle } from '../setting';
|
||||
import * as styles from './subscription-setting.css';
|
||||
|
||||
export const SubscriptionSetting = ({
|
||||
@@ -18,7 +19,7 @@ export const SubscriptionSetting = ({
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const calendar = useService(IntegrationService).calendar;
|
||||
const config = useLiveData(subscription.config$);
|
||||
const name = useLiveData(subscription.name$);
|
||||
const name = useLiveData(subscription.name$) || t['Untitled']();
|
||||
|
||||
const handleColorChange = useCallback(
|
||||
(color: string) => {
|
||||
@@ -28,9 +29,17 @@ export const SubscriptionSetting = ({
|
||||
[calendar, subscription.url]
|
||||
);
|
||||
|
||||
const handleUnsubscribe = useCallback(() => {
|
||||
calendar.deleteSubscription(subscription.url);
|
||||
}, [calendar, subscription.url]);
|
||||
const toggleShowEvents = useCallback(() => {
|
||||
calendar.updateSubscription(subscription.url, {
|
||||
showEvents: !config?.showEvents,
|
||||
});
|
||||
}, [calendar, subscription.url, config?.showEvents]);
|
||||
|
||||
const toggleShowAllDayEvents = useCallback(() => {
|
||||
calendar.updateSubscription(subscription.url, {
|
||||
showAllDayEvents: !config?.showAllDayEvents,
|
||||
});
|
||||
}, [calendar, subscription.url, config?.showAllDayEvents]);
|
||||
|
||||
if (!config) return null;
|
||||
|
||||
@@ -52,15 +61,61 @@ export const SubscriptionSetting = ({
|
||||
style={{ color: config.color }}
|
||||
/>
|
||||
</Menu>
|
||||
<div className={styles.name}>{name || t['Untitled']()}</div>
|
||||
<Button variant="error" onClick={handleUnsubscribe}>
|
||||
{t['com.affine.integration.calendar.unsubscribe']()}
|
||||
</Button>
|
||||
<div className={styles.name}>{name}</div>
|
||||
<UnsubscribeButton url={subscription.url} name={name} />
|
||||
</div>
|
||||
<div className={styles.divider} />
|
||||
<IntegrationSettingToggle
|
||||
name={t['com.affine.integration.calendar.show-events']()}
|
||||
desc={t['com.affine.integration.calendar.show-events-desc']()}
|
||||
checked={!!config.showEvents}
|
||||
onChange={toggleShowEvents}
|
||||
/>
|
||||
<div
|
||||
data-collapsed={!config.showEvents}
|
||||
className={styles.allDayEventsContainer}
|
||||
>
|
||||
<div className={styles.allDayEventsContent}>
|
||||
<div className={styles.divider} />
|
||||
<IntegrationSettingToggle
|
||||
name={t['com.affine.integration.calendar.show-all-day-events']()}
|
||||
checked={!!config.showAllDayEvents}
|
||||
onChange={toggleShowAllDayEvents}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const UnsubscribeButton = ({ url, name }: { url: string; name: string }) => {
|
||||
const t = useI18n();
|
||||
const calendar = useService(IntegrationService).calendar;
|
||||
const { openConfirmModal } = useConfirmModal();
|
||||
|
||||
const handleUnsubscribe = useCallback(() => {
|
||||
openConfirmModal({
|
||||
title: t['com.affine.integration.calendar.unsubscribe'](),
|
||||
children: t.t('com.affine.integration.calendar.unsubscribe-content', {
|
||||
name,
|
||||
}),
|
||||
onConfirm: () => {
|
||||
calendar.deleteSubscription(url);
|
||||
},
|
||||
confirmText: t['com.affine.integration.calendar.unsubscribe'](),
|
||||
confirmButtonOptions: {
|
||||
variant: 'error',
|
||||
},
|
||||
});
|
||||
}, [calendar, name, openConfirmModal, t, url]);
|
||||
|
||||
return (
|
||||
<Button variant="error" onClick={handleUnsubscribe}>
|
||||
{t['com.affine.integration.calendar.unsubscribe']()}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
const ColorPicker = ({
|
||||
activeColor,
|
||||
onChange,
|
||||
|
||||
+6
@@ -42,6 +42,11 @@ export const settingItem = style({
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
gap: 8,
|
||||
selectors: {
|
||||
'&[data-has-desc="false"]': {
|
||||
padding: '5px 0',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const settingName = style({
|
||||
@@ -56,6 +61,7 @@ export const settingDesc = style({
|
||||
lineHeight: '20px',
|
||||
fontWeight: 400,
|
||||
color: cssVarV2.text.secondary,
|
||||
marginTop: 2,
|
||||
});
|
||||
|
||||
export const textRadioGroup = style({
|
||||
|
||||
+5
-1
@@ -47,7 +47,11 @@ export const IntegrationSettingItem = ({
|
||||
...props
|
||||
}: IntegrationSettingItemProps) => {
|
||||
return (
|
||||
<div className={clsx(styles.settingItem, className)} {...props}>
|
||||
<div
|
||||
data-has-desc={!!desc}
|
||||
className={clsx(styles.settingItem, className)}
|
||||
{...props}
|
||||
>
|
||||
<div>
|
||||
{name && <h6 className={styles.settingName}>{name}</h6>}
|
||||
{desc && <p className={styles.settingDesc}>{desc}</p>}
|
||||
|
||||
Reference in New Issue
Block a user