mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
chore: enhance layout
This commit is contained in:
parent
1a91bdc2e9
commit
282d2b9455
8 changed files with 144 additions and 100 deletions
|
|
@ -54,7 +54,7 @@ function SettingsBarContent() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<h3 className={'gitako-settings-bar-title'}>Settings</h3>
|
||||
<h2 className={'gitako-settings-bar-title'}>Settings</h2>
|
||||
<div className={'gitako-settings-bar-content'}>
|
||||
<div className={'shadow-shelter'} />
|
||||
<AccessTokenSettings />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
import { Field } from './settings/Field'
|
||||
import { SimpleField } from './SettingsBar'
|
||||
|
||||
type Props = {
|
||||
|
|
@ -13,7 +13,23 @@ export function SimpleToggleField({ field, onChange }: Props) {
|
|||
const configContext = useConfigs()
|
||||
const value = configContext.val[field.key]
|
||||
return (
|
||||
<div className={cx('field', 'field-checkbox')}>
|
||||
<Field
|
||||
id={field.key}
|
||||
title={
|
||||
<>
|
||||
{field.label}{' '}
|
||||
{field.wikiLink ? (
|
||||
<a href={field.wikiLink} target={'_blank'}>
|
||||
(?)
|
||||
</a>
|
||||
) : (
|
||||
field.description && <p className={'note'}>{field.description}</p>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
className={'field-checkbox'}
|
||||
checkbox
|
||||
>
|
||||
<input
|
||||
id={field.key}
|
||||
name={field.key}
|
||||
|
|
@ -25,16 +41,6 @@ export function SimpleToggleField({ field, onChange }: Props) {
|
|||
}}
|
||||
checked={overwrite ? overwrite.value(value) : Boolean(value)}
|
||||
/>
|
||||
<label htmlFor={field.key}>
|
||||
{field.label}{' '}
|
||||
{field.wikiLink ? (
|
||||
<a href={field.wikiLink} target={'_blank'}>
|
||||
(?)
|
||||
</a>
|
||||
) : (
|
||||
field.description && <p className={'note'}>{field.description}</p>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,50 +62,48 @@ export function AccessTokenSettings(props: React.PropsWithChildren<Props>) {
|
|||
return (
|
||||
<SettingsSection
|
||||
title={
|
||||
<span>
|
||||
Access Token
|
||||
<>
|
||||
Access Token{' '}
|
||||
<a href={wikiLinks.createAccessToken} target="_blank">
|
||||
{' '}
|
||||
(?)
|
||||
</a>
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{!hasAccessToken && (
|
||||
<a
|
||||
className={'link-button'}
|
||||
onClick={() => {
|
||||
// use js here to make sure redirect_uri is latest url
|
||||
const url = `https://github.com/login/oauth/authorize?client_id=${
|
||||
oauth.clientId
|
||||
}&scope=repo&redirect_uri=${encodeURIComponent(window.location.href)}`
|
||||
window.location.href = url
|
||||
}}
|
||||
>
|
||||
Create with OAuth (recommended)
|
||||
</a>
|
||||
{hasAccessToken ? (
|
||||
<Button onClick={() => configContext.set({ access_token: '' })}>Clear</Button>
|
||||
) : (
|
||||
<div>
|
||||
<a
|
||||
className={'link-button'}
|
||||
onClick={() => {
|
||||
// use js here to make sure redirect_uri is latest url
|
||||
const url = `https://github.com/login/oauth/authorize?client_id=${
|
||||
oauth.clientId
|
||||
}&scope=repo&redirect_uri=${encodeURIComponent(window.location.href)}`
|
||||
window.location.href = url
|
||||
}}
|
||||
>
|
||||
Create with OAuth (recommended)
|
||||
</a>
|
||||
<div className={'access-token-input-control'}>
|
||||
<TextInput
|
||||
backgroundColor="#fff"
|
||||
marginRight={1}
|
||||
className={'access-token-input'}
|
||||
value={accessToken}
|
||||
placeholder="Or input here manually"
|
||||
onFocus={() => focusInput.set(true)}
|
||||
onBlur={() => focusInput.set(false)}
|
||||
onChange={onInputAccessToken}
|
||||
onKeyPress={onPressAccessToken}
|
||||
/>
|
||||
<Button onClick={() => saveToken()} disabled={!accessToken}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={'access-token-input-control'}>
|
||||
<TextInput
|
||||
backgroundColor="#fff"
|
||||
marginRight={1}
|
||||
className={'access-token-input'}
|
||||
disabled={hasAccessToken}
|
||||
placeholder={hasAccessToken ? 'Your token is saved' : 'Or input here manually'}
|
||||
value={accessToken}
|
||||
onFocus={() => focusInput.set(true)}
|
||||
onBlur={() => focusInput.set(false)}
|
||||
onChange={onInputAccessToken}
|
||||
onKeyPress={onPressAccessToken}
|
||||
/>
|
||||
{hasAccessToken && !accessToken ? (
|
||||
<Button onClick={() => configContext.set({ access_token: '' })}>Clear</Button>
|
||||
) : (
|
||||
<Button onClick={() => saveToken()} disabled={!accessToken}>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{accessTokenHint && !focusInput.val && <span className={'hint'}>{accessTokenHint}</span>}
|
||||
</SettingsSection>
|
||||
)
|
||||
|
|
|
|||
33
src/components/settings/Field.tsx
Normal file
33
src/components/settings/Field.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import * as React from 'react'
|
||||
import { cx } from 'utils/cx'
|
||||
|
||||
type Props = {
|
||||
id?: string
|
||||
className?: string
|
||||
checkbox?: boolean
|
||||
title: React.ReactNode
|
||||
}
|
||||
|
||||
export function Field({
|
||||
className,
|
||||
title,
|
||||
id,
|
||||
checkbox,
|
||||
children,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<div className={cx('field', className)}>
|
||||
{checkbox ? (
|
||||
<>
|
||||
{children}
|
||||
<label htmlFor={id}>{title}</label>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<label htmlFor={id}>{title}</label>
|
||||
<div>{children}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import { SimpleToggleField } from 'components/SimpleToggleField'
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { Config } from 'utils/configHelper'
|
||||
import { Field } from './Field'
|
||||
import { SettingsSection } from './SettingsSection'
|
||||
|
||||
const options: {
|
||||
|
|
@ -33,27 +34,23 @@ export function FileTreeSettings(props: React.PropsWithChildren<Props>) {
|
|||
const configContext = useConfigs()
|
||||
return (
|
||||
<SettingsSection title={'File Tree'}>
|
||||
<div className={'field'}>
|
||||
<label htmlFor="file-tree-icons">Icons</label>
|
||||
<div>
|
||||
<select
|
||||
id="file-tree-icons"
|
||||
onChange={e => {
|
||||
configContext.set({
|
||||
icons: e.target.value as Config['icons'],
|
||||
})
|
||||
}}
|
||||
className={'file-tree-input form-control'}
|
||||
value={configContext.val.icons}
|
||||
>
|
||||
{options.map(option => (
|
||||
<option key={option.key} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<Field title="Icons" id="file-tree-icons">
|
||||
<select
|
||||
id="file-tree-icons"
|
||||
onChange={e => {
|
||||
configContext.set({
|
||||
icons: e.target.value as Config['icons'],
|
||||
})
|
||||
}}
|
||||
value={configContext.val.icons}
|
||||
>
|
||||
{options.map(option => (
|
||||
<option key={option.key} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
<SimpleToggleField
|
||||
field={{
|
||||
key: 'compressSingletonFolder',
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import * as React from 'react'
|
||||
type Props = {
|
||||
title: React.ReactNode
|
||||
title?: React.ReactNode
|
||||
}
|
||||
|
||||
export function SettingsSection({ title, children }: React.PropsWithChildren<Props>) {
|
||||
return (
|
||||
<div className={'settings-section'}>
|
||||
<h4>{title}</h4>
|
||||
{title && <h3>{title}</h3>}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import * as React from 'react'
|
|||
import { friendlyFormatShortcut } from 'utils/general'
|
||||
import { useStates } from 'utils/hooks/useStates'
|
||||
import * as keyHelper from 'utils/keyHelper'
|
||||
import { Field } from './Field'
|
||||
import { SettingsSection } from './SettingsSection'
|
||||
|
||||
type Props = {}
|
||||
|
|
@ -21,8 +22,7 @@ export function SidebarSettings(props: React.PropsWithChildren<Props>) {
|
|||
|
||||
return (
|
||||
<SettingsSection title={'Toggle Sidebar'}>
|
||||
<div className={'field'}>
|
||||
<label htmlFor="toggle-sidebar-shortcut">Keyboard Shortcut</label>
|
||||
<Field id="toggle-sidebar-shortcut" title="Keyboard Shortcut">
|
||||
<div className={'toggle-shortcut-input-control'}>
|
||||
<TextInput
|
||||
id="toggle-sidebar-shortcut"
|
||||
|
|
@ -42,18 +42,28 @@ export function SidebarSettings(props: React.PropsWithChildren<Props>) {
|
|||
}, [])}
|
||||
readOnly
|
||||
/>
|
||||
<Button
|
||||
disabled={toggleShowSideBarShortcut === configContext.val.shortcut}
|
||||
onClick={() => {
|
||||
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
|
||||
if (typeof toggleShowSideBarShortcut !== 'string') return
|
||||
configContext.set({ shortcut: toggleShowSideBarShortcut })
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
{configContext.val.shortcut === toggleShowSideBarShortcut ? (
|
||||
<Button
|
||||
disabled={!configContext.val.shortcut}
|
||||
onClick={() => {
|
||||
configContext.set({ shortcut: '' })
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
onClick={() => {
|
||||
const { val: toggleShowSideBarShortcut } = useToggleShowSideBarShortcut
|
||||
if (typeof toggleShowSideBarShortcut !== 'string') return
|
||||
configContext.set({ shortcut: toggleShowSideBarShortcut })
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Field>
|
||||
<SimpleToggleField
|
||||
field={{
|
||||
key: 'intelligentToggle',
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
max-height: 100%;
|
||||
&-title {
|
||||
border-top: 1px solid $border-gray-light;
|
||||
padding: 6px 10px;
|
||||
padding: 10px;
|
||||
box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14),
|
||||
0 3px 3px -2px rgba(0, 0, 0, 0.12);
|
||||
z-index: 1;
|
||||
|
|
@ -439,7 +439,7 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
}
|
||||
.settings-section {
|
||||
&:not(:last-of-type) {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.field {
|
||||
|
|
@ -448,7 +448,16 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
}
|
||||
input {
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
select {
|
||||
width: 100%;
|
||||
background: $bg-white;
|
||||
}
|
||||
&.field-checkbox {
|
||||
padding-left: 20px;
|
||||
|
|
@ -457,21 +466,12 @@ $minimal-z-index: max($github-header-z-index, $github-pull-request-float-header-
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
input[type='checkbox'],
|
||||
input[type='radio'] {
|
||||
float: left;
|
||||
margin: 5px 0 0 -20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
background: $bg-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue