mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
mobile: update ui
This commit is contained in:
committed by
Abdullah Atta
parent
bbb4a9d44a
commit
3b362f592c
@@ -55,9 +55,7 @@ import FormInput, {
|
||||
createFormRef,
|
||||
validators
|
||||
} from "../../ui/input/form-input";
|
||||
import Paragraph from "../../ui/typography/paragraph";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { DefaultAppStyles } from "../../../utils/styles";
|
||||
import {
|
||||
isEncryptedContent,
|
||||
Note,
|
||||
@@ -72,6 +70,7 @@ import { Radius, Spacing } from "../../../common/design/spacing";
|
||||
import { PASSWORD_PLACEHOLDER } from "../../../utils/constants";
|
||||
import { AppFontSize } from "../../../utils/size";
|
||||
import { useSettingStore } from "../../../stores/use-setting-store";
|
||||
import { Checkbox } from "../../ui/checkbox";
|
||||
|
||||
export const VaultDialog: React.FC = () => {
|
||||
const { colors } = useThemeColors();
|
||||
@@ -632,7 +631,7 @@ export const VaultDialog: React.FC = () => {
|
||||
descriptionRef.current = data.description || null;
|
||||
paragraphRef.current = data.paragraph || null;
|
||||
buttonTitleRef.current = data.buttonTitle || null;
|
||||
positiveButtonTypeRef.current = data.positiveButtonType || "transparent";
|
||||
positiveButtonTypeRef.current = data.positiveButtonType || "accent";
|
||||
customActionTitleRef.current = data.customActionTitle || null;
|
||||
customActionParagraphRef.current = data.customActionParagraph || null;
|
||||
onUnlockRef.current = data.onUnlock;
|
||||
@@ -641,7 +640,7 @@ export const VaultDialog: React.FC = () => {
|
||||
// Set UI state
|
||||
setIsBiometryAvailable(available);
|
||||
setIsBiometryEnrolled(fingerprint);
|
||||
setBiometricUnlock(fingerprint);
|
||||
// setBiometricUnlock(fingerprint);
|
||||
setIcon(data.icon);
|
||||
setDeleteAll(false);
|
||||
setLoading(false);
|
||||
@@ -719,7 +718,11 @@ export const VaultDialog: React.FC = () => {
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={titleRef.current}
|
||||
title={
|
||||
requestType === VaultRequestType.PermanentUnlock
|
||||
? noteRef.current?.title
|
||||
: titleRef.current
|
||||
}
|
||||
paragraph={
|
||||
paragraphRef.current || customActionParagraphRef.current || ""
|
||||
}
|
||||
@@ -737,7 +740,7 @@ export const VaultDialog: React.FC = () => {
|
||||
paddingHorizontal: Spacing.LEVEL_3,
|
||||
gap: isDeleteVault ? 0 : Spacing.LEVEL_4,
|
||||
marginTop: Spacing.LEVEL_4,
|
||||
marginBottom: Spacing.LEVEL_1
|
||||
marginBottom: Spacing.LEVEL_4
|
||||
}}
|
||||
>
|
||||
{(isChangePassword ||
|
||||
@@ -841,9 +844,14 @@ export const VaultDialog: React.FC = () => {
|
||||
) : null}
|
||||
|
||||
{isCreateVault ? (
|
||||
<View>
|
||||
<View
|
||||
style={{
|
||||
gap: Spacing.LEVEL_2
|
||||
}}
|
||||
>
|
||||
<FormInput
|
||||
name="password"
|
||||
label={strings.password()}
|
||||
formRef={formRef}
|
||||
fwdRef={passInputRef}
|
||||
autoCapitalize="none"
|
||||
@@ -886,12 +894,7 @@ export const VaultDialog: React.FC = () => {
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{biometricUnlock && !isBiometryEnrolled && !isCreateVault ? (
|
||||
<Paragraph>{strings.vaultEnableBiometrics()}</Paragraph>
|
||||
) : null}
|
||||
|
||||
{!biometricUnlock &&
|
||||
!isBiometryEnrolled &&
|
||||
{!isBiometryEnrolled &&
|
||||
isBiometryAvailable &&
|
||||
(requestType === VaultRequestType.CopyNote ||
|
||||
requestType === VaultRequestType.DeleteNote ||
|
||||
@@ -900,20 +903,16 @@ export const VaultDialog: React.FC = () => {
|
||||
requestType === VaultRequestType.GoToEditor ||
|
||||
requestType === VaultRequestType.PermanentUnlock ||
|
||||
requestType === VaultRequestType.LockNote) ? (
|
||||
<Button
|
||||
<Checkbox
|
||||
title={strings.vaultEnableBiometrics()}
|
||||
checked={biometricUnlock}
|
||||
iconSize={12}
|
||||
style={{
|
||||
marginTop: -Spacing.LEVEL_1
|
||||
}}
|
||||
onPress={() => {
|
||||
setBiometricUnlock(!biometricUnlock);
|
||||
}}
|
||||
style={{
|
||||
marginTop: DefaultAppStyles.GAP_VERTICAL
|
||||
}}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title={strings.unlockWithBiometrics()}
|
||||
iconColor={
|
||||
biometricUnlock ? colors.selected.accent : colors.primary.icon
|
||||
}
|
||||
type={biometricUnlock ? "transparent" : "plain"}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -57,7 +57,8 @@ export const NotebookItem = ({
|
||||
disableExpand,
|
||||
hideNoteCount,
|
||||
style,
|
||||
subNotebookButtonStyle
|
||||
subNotebookButtonStyle,
|
||||
selectionCheckboxLocation = "right"
|
||||
}: {
|
||||
index: number;
|
||||
item: TreeItem;
|
||||
@@ -76,6 +77,7 @@ export const NotebookItem = ({
|
||||
hideNoteCount?: boolean;
|
||||
style?: ViewStyle;
|
||||
subNotebookButtonStyle?: ViewStyle;
|
||||
selectionCheckboxLocation?: "left" | "right";
|
||||
}) => {
|
||||
const notebook = item.notebook;
|
||||
const isFocused = focused;
|
||||
@@ -194,7 +196,8 @@ export const NotebookItem = ({
|
||||
gap: Spacing.LEVEL_1
|
||||
}}
|
||||
>
|
||||
{item.depth === 0 ? (
|
||||
{item.depth === 0 &&
|
||||
(!selectionEnabled || selectionCheckboxLocation === "right") ? (
|
||||
<AppIcon
|
||||
size={AppFontSize.md}
|
||||
color={
|
||||
@@ -211,11 +214,34 @@ export const NotebookItem = ({
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{selectionEnabled && selectionCheckboxLocation === "left" ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
}}
|
||||
>
|
||||
<AppIcon
|
||||
name={selected ? "checkbox" : "box-empty"}
|
||||
iconFamily="notesnook"
|
||||
size={16}
|
||||
color={
|
||||
selected
|
||||
? [
|
||||
colors.selected.accent,
|
||||
colors.selected.accentForeground
|
||||
]
|
||||
: colors.primary.icon
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
<Paragraph
|
||||
color={
|
||||
isFocused ? colors.selected.paragraph : colors.primary.paragraph
|
||||
}
|
||||
size={AppFontSize.sm}
|
||||
fontSize="SM"
|
||||
>
|
||||
{notebook?.title}
|
||||
</Paragraph>
|
||||
@@ -229,7 +255,7 @@ export const NotebookItem = ({
|
||||
justifyContent: "center"
|
||||
}}
|
||||
>
|
||||
{selectionEnabled ? (
|
||||
{selectionEnabled && selectionCheckboxLocation === "right" ? (
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
@@ -239,7 +265,7 @@ export const NotebookItem = ({
|
||||
<AppIcon
|
||||
name={selected ? "checkbox" : "box-empty"}
|
||||
iconFamily="notesnook"
|
||||
size={AppFontSize.md}
|
||||
size={16}
|
||||
color={
|
||||
selected
|
||||
? [
|
||||
@@ -250,17 +276,15 @@ export const NotebookItem = ({
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
{item.hasChildren || hideNoteCount ? null : (
|
||||
<Paragraph fontSize="SM" color={colors.secondary.paragraph}>
|
||||
{totalNotes?.(notebook?.id) || 0}
|
||||
</Paragraph>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{item.hasChildren || hideNoteCount || selectionEnabled ? null : (
|
||||
<Paragraph fontSize="SM" color={colors.secondary.paragraph}>
|
||||
{totalNotes?.(notebook?.id) || 0}
|
||||
</Paragraph>
|
||||
)}
|
||||
|
||||
{onAddNotebook ? (
|
||||
{onAddNotebook && !item.hasChildren ? (
|
||||
<IconButton
|
||||
name="plus"
|
||||
iconFamily="notesnook"
|
||||
@@ -303,7 +327,8 @@ export const NotebookItem = ({
|
||||
style={{
|
||||
borderRadius: defaultBorderRadius,
|
||||
width: undefined,
|
||||
height: undefined
|
||||
height: undefined,
|
||||
marginRight: 1.5
|
||||
}}
|
||||
iconFamily="notesnook"
|
||||
name={expanded ? "chevron-up" : "chevron-down"}
|
||||
@@ -313,7 +338,7 @@ export const NotebookItem = ({
|
||||
</Pressable>
|
||||
</View>
|
||||
|
||||
{expanded && item.hasChildren && !selectionEnabled ? (
|
||||
{expanded && item.hasChildren ? (
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
|
||||
@@ -77,7 +77,7 @@ export const Checkbox = ({
|
||||
style={{
|
||||
width: width || undefined,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "flex-start",
|
||||
flexShrink: 1,
|
||||
gap: Spacing.LEVEL_1,
|
||||
@@ -92,6 +92,9 @@ export const Checkbox = ({
|
||||
name={checked ? "checkbox" : "box-empty"}
|
||||
iconFamily="notesnook"
|
||||
size={iconSize}
|
||||
style={{
|
||||
marginTop: 1.5
|
||||
}}
|
||||
color={
|
||||
iconColor ||
|
||||
(checked
|
||||
@@ -102,7 +105,7 @@ export const Checkbox = ({
|
||||
|
||||
{title ? (
|
||||
<Paragraph
|
||||
numberOfLines={1}
|
||||
numberOfLines={2}
|
||||
size={fontSize}
|
||||
fontFamily={fontFamily}
|
||||
color={colors.primary.paragraph}
|
||||
|
||||
@@ -98,7 +98,6 @@ export const IconButton = ({
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
// borderRadius: 100,
|
||||
width: size,
|
||||
height: size,
|
||||
...style
|
||||
|
||||
@@ -185,13 +185,13 @@ export function hasFormErrors(errors: FormErrors) {
|
||||
export const validators = {
|
||||
required:
|
||||
(message = "This field is required") =>
|
||||
(value: string) =>
|
||||
value?.trim() ? undefined : message,
|
||||
(value: string) =>
|
||||
value?.trim() ? undefined : message,
|
||||
|
||||
email:
|
||||
(message = "Please enter a valid email") =>
|
||||
(value: string) =>
|
||||
!value?.trim() || isEmail(value.trim()) ? undefined : message,
|
||||
(value: string) =>
|
||||
!value?.trim() || isEmail(value.trim()) ? undefined : message,
|
||||
|
||||
minLength: (length: number, message?: string) => (value: string) =>
|
||||
!value || value.length >= length
|
||||
@@ -200,15 +200,15 @@ export const validators = {
|
||||
|
||||
url:
|
||||
(message = "Please enter a valid URL") =>
|
||||
(value: string) =>
|
||||
!value?.trim() || isURL(value.trim(), { allow_underscores: true })
|
||||
? undefined
|
||||
: message,
|
||||
(value: string) =>
|
||||
!value?.trim() || isURL(value.trim(), { allow_underscores: true })
|
||||
? undefined
|
||||
: message,
|
||||
|
||||
matchField:
|
||||
(fieldName: string, message = "Values do not match") =>
|
||||
(value: string, values: FormValues) =>
|
||||
value === values[fieldName] ? undefined : message
|
||||
(value: string, values: FormValues) =>
|
||||
value === values[fieldName] ? undefined : message
|
||||
};
|
||||
|
||||
interface FormInputProps extends TextInputProps {
|
||||
@@ -388,7 +388,7 @@ export function FormInput({
|
||||
<IconButton
|
||||
name={!secureEntry ? "eye-closed" : "eye-open"}
|
||||
iconFamily="notesnook"
|
||||
size={20}
|
||||
size={16}
|
||||
top={10}
|
||||
bottom={10}
|
||||
onPress={() => {
|
||||
@@ -409,7 +409,7 @@ export function FormInput({
|
||||
<IconButton
|
||||
testID={button.testID}
|
||||
name={button.icon}
|
||||
size={button.size || AppFontSize.xl}
|
||||
size={button.size || 16}
|
||||
top={10}
|
||||
bottom={10}
|
||||
onPress={button.onPress}
|
||||
|
||||
@@ -941,6 +941,7 @@ export const useActions = ({
|
||||
requestType: VaultRequestType.PermanentUnlock,
|
||||
item: item,
|
||||
title: strings.unlockNote(),
|
||||
paragraph: strings.thisNoteLocked(),
|
||||
buttonTitle: strings.unlock()
|
||||
});
|
||||
return;
|
||||
@@ -962,7 +963,8 @@ export const useActions = ({
|
||||
requestType: VaultRequestType.CreateVault,
|
||||
item: item,
|
||||
title: strings.createVault(),
|
||||
buttonTitle: strings.lock()
|
||||
buttonTitle: strings.lock(),
|
||||
positiveButtonType: "accent"
|
||||
});
|
||||
break;
|
||||
case VAULT_ERRORS.vaultLocked:
|
||||
@@ -970,7 +972,8 @@ export const useActions = ({
|
||||
requestType: VaultRequestType.LockNote,
|
||||
item: item,
|
||||
title: strings.lockNote(),
|
||||
buttonTitle: strings.lock()
|
||||
buttonTitle: strings.lock(),
|
||||
positiveButtonType: "accent"
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ export const Home = ({ navigation, route }: NavigationProps<"Notes">) => {
|
||||
});
|
||||
}}
|
||||
id={route.name}
|
||||
style={{
|
||||
paddingHorizontal: Spacing.LEVEL_2
|
||||
}}
|
||||
onPressDefaultRightButton={openEditor}
|
||||
/>
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { ActivityIndicator, View } from "react-native";
|
||||
import { FlatList } from "react-native-actions-sheet";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import { db } from "../../common/database";
|
||||
import { Spacing } from "../../common/design/spacing";
|
||||
import Navigation, { NavigationProps } from "../../services/navigation";
|
||||
import {
|
||||
createNotebookTreeStores,
|
||||
@@ -35,10 +36,9 @@ import { useNotebooks } from "../../stores/use-notebook-store";
|
||||
import { useRelationStore } from "../../stores/use-relation-store";
|
||||
import { updateNotebook } from "../../utils/notebooks";
|
||||
import { AppFontSize } from "../../utils/size";
|
||||
import { DefaultAppStyles } from "../../utils/styles";
|
||||
import { FloatingButton } from "../../components/container/floating-button";
|
||||
import { Header } from "../../components/header";
|
||||
import { NotebookItem } from "../../components/side-menu/notebook-item";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import Input from "../../components/ui/input";
|
||||
import Paragraph from "../../components/ui/typography/paragraph";
|
||||
import { AddNotebookSheet } from "../../components/sheets/add-notebook";
|
||||
@@ -193,10 +193,35 @@ const LinkNotebooks = (props: NavigationProps<"LinkNotebooks">) => {
|
||||
[]
|
||||
);
|
||||
|
||||
const onCreateNotebook = async () => {
|
||||
const notebooksFeature = await isFeatureAvailable("notebooks");
|
||||
if (!notebooksFeature.isAllowed) {
|
||||
ToastManager.show({
|
||||
message: notebooksFeature.error,
|
||||
type: "info",
|
||||
context: "local",
|
||||
actionText: strings.upgrade(),
|
||||
func: () => {
|
||||
ToastManager.hide();
|
||||
PaywallSheet.present(notebooksFeature);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
AddNotebookSheet.present(
|
||||
undefined,
|
||||
undefined,
|
||||
"global",
|
||||
undefined,
|
||||
false,
|
||||
searchQuery.current
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={{
|
||||
gap: DefaultAppStyles.GAP_VERTICAL,
|
||||
gap: Spacing.LEVEL_2,
|
||||
flex: 1,
|
||||
backgroundColor: colors.primary.background
|
||||
}}
|
||||
@@ -204,10 +229,15 @@ const LinkNotebooks = (props: NavigationProps<"LinkNotebooks">) => {
|
||||
<Header
|
||||
title={strings.addToNotebook()}
|
||||
canGoBack
|
||||
style={{
|
||||
backgroundColor: colors.primary.background
|
||||
}}
|
||||
rightButton={
|
||||
hasSelection
|
||||
? {
|
||||
name: "restore",
|
||||
name: "arrow-counter-clockwise",
|
||||
iconFamily: "notesnook",
|
||||
size: 20,
|
||||
onPress: () => {
|
||||
updateInitialSelectionState(noteIds);
|
||||
}
|
||||
@@ -225,9 +255,10 @@ const LinkNotebooks = (props: NavigationProps<"LinkNotebooks">) => {
|
||||
ListHeaderComponent={
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: DefaultAppStyles.GAP,
|
||||
paddingHorizontal: Spacing.LEVEL_3,
|
||||
width: "100%",
|
||||
paddingVertical: DefaultAppStyles.GAP_VERTICAL
|
||||
paddingBottom: Spacing.LEVEL_3,
|
||||
gap: Spacing.LEVEL_3
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
@@ -238,35 +269,33 @@ const LinkNotebooks = (props: NavigationProps<"LinkNotebooks">) => {
|
||||
updateNotebooks();
|
||||
}, 300);
|
||||
}}
|
||||
button={{
|
||||
icon: "plus",
|
||||
onPress: async () => {
|
||||
const notebooksFeature =
|
||||
await isFeatureAvailable("notebooks");
|
||||
if (!notebooksFeature.isAllowed) {
|
||||
ToastManager.show({
|
||||
message: notebooksFeature.error,
|
||||
type: "info",
|
||||
context: "local",
|
||||
actionText: strings.upgrade(),
|
||||
func: () => {
|
||||
ToastManager.hide();
|
||||
PaywallSheet.present(notebooksFeature);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
AddNotebookSheet.present(
|
||||
undefined,
|
||||
undefined,
|
||||
"global",
|
||||
undefined,
|
||||
false,
|
||||
searchQuery.current
|
||||
);
|
||||
},
|
||||
color: colors.primary.icon
|
||||
containerStyle={{
|
||||
backgroundColor: colors.secondary.background,
|
||||
borderWidth: 0
|
||||
}}
|
||||
button={{
|
||||
icon: "search",
|
||||
iconFamily: "notesnook",
|
||||
onPress: () => {},
|
||||
color: colors.secondary.icon,
|
||||
size: 16
|
||||
}}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
height: 1,
|
||||
backgroundColor: colors.primary.border
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
title={strings.createNotebook()}
|
||||
icon="plus"
|
||||
iconPosition="left"
|
||||
type="accent-outline"
|
||||
width="100%"
|
||||
onPress={onCreateNotebook}
|
||||
/>
|
||||
|
||||
{!multiSelect ? (
|
||||
@@ -302,14 +331,23 @@ const LinkNotebooks = (props: NavigationProps<"LinkNotebooks">) => {
|
||||
}
|
||||
/>
|
||||
|
||||
{hasSelection ? (
|
||||
<FloatingButton
|
||||
<View
|
||||
style={{
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.primary.border,
|
||||
backgroundColor: colors.primary.background,
|
||||
padding: Spacing.LEVEL_3
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
testID="floating-save-button"
|
||||
icon="check"
|
||||
alwaysVisible
|
||||
title={strings.saveChanges()}
|
||||
type="accent"
|
||||
width="100%"
|
||||
disabled={!hasSelection}
|
||||
onPress={() => onSave()}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
@@ -357,12 +395,13 @@ const NotebookItemWrapper = React.memo(
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: DefaultAppStyles.GAP
|
||||
paddingHorizontal: Spacing.LEVEL_3
|
||||
}}
|
||||
>
|
||||
<NotebookItem
|
||||
item={item}
|
||||
index={index}
|
||||
selectionCheckboxLocation="left"
|
||||
expanded={expanded}
|
||||
onToggleExpanded={async () => {
|
||||
useNotebookExpandedStore.getState().setExpanded(item.notebook.id);
|
||||
@@ -395,6 +434,12 @@ const NotebookItemWrapper = React.memo(
|
||||
: "deselected"
|
||||
);
|
||||
}}
|
||||
style={{
|
||||
paddingVertical: Spacing.LEVEL_1
|
||||
}}
|
||||
subNotebookButtonStyle={{
|
||||
paddingVertical: Spacing.LEVEL_1
|
||||
}}
|
||||
canDisableSelectionMode={false}
|
||||
selected={selected}
|
||||
selectionEnabled={selectionEnabled}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
11
packages/icons/svgs/eye-open.svg
Normal file → Executable file
11
packages/icons/svgs/eye-open.svg
Normal file → Executable file
@@ -1 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE --><path fill="currentColor" d="M245.48 125.57c-.34-.78-8.66-19.23-27.24-37.81C201 70.54 171.38 50 128 50S55 70.54 37.76 87.76c-18.58 18.58-26.9 37-27.24 37.81a6 6 0 0 0 0 4.88c.34.77 8.66 19.22 27.24 37.8C55 185.47 84.62 206 128 206s73-20.53 90.24-37.75c18.58-18.58 26.9-37 27.24-37.8a6 6 0 0 0 0-4.88M128 194c-31.38 0-58.78-11.42-81.45-33.93A134.8 134.8 0 0 1 22.69 128a134.6 134.6 0 0 1 23.86-32.06C69.22 73.42 96.62 62 128 62s58.78 11.42 81.45 33.94A134.6 134.6 0 0 1 233.31 128C226.94 140.21 195 194 128 194m0-112a46 46 0 1 0 46 46a46.06 46.06 0 0 0-46-46m0 80a34 34 0 1 1 34-34a34 34 0 0 1-34 34"/></svg>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2899_8437)">
|
||||
<path d="M7.99935 3C4.66602 3 1.81935 5.07333 0.666016 8C1.81935 10.9267 4.66602 13 7.99935 13C11.3327 13 14.1793 10.9267 15.3327 8C14.1793 5.07333 11.3327 3 7.99935 3ZM7.99935 11.3333C6.15935 11.3333 4.66602 9.84 4.66602 8C4.66602 6.16 6.15935 4.66667 7.99935 4.66667C9.83935 4.66667 11.3327 6.16 11.3327 8C11.3327 9.84 9.83935 11.3333 7.99935 11.3333ZM7.99935 6C6.89268 6 5.99935 6.89333 5.99935 8C5.99935 9.10667 6.89268 10 7.99935 10C9.10602 10 9.99935 9.10667 9.99935 8C9.99935 6.89333 9.10602 6 7.99935 6Z" fill="#666666"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2899_8437">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 796 B After Width: | Height: | Size: 779 B |
Reference in New Issue
Block a user