mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-24 02:11:10 +01:00
Obscure text
This commit is contained in:
@@ -7,23 +7,22 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate objc;
|
extern crate objc;
|
||||||
|
|
||||||
use base64::Engine;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::fs::create_dir_all;
|
use std::fs::create_dir_all;
|
||||||
|
|
||||||
use http::header::{HeaderName, ACCEPT, USER_AGENT};
|
use base64::Engine;
|
||||||
use http::{HeaderMap, HeaderValue, Method};
|
use http::{HeaderMap, HeaderValue, Method};
|
||||||
|
use http::header::{ACCEPT, HeaderName, USER_AGENT};
|
||||||
use reqwest::redirect::Policy;
|
use reqwest::redirect::Policy;
|
||||||
use serde::Serialize;
|
use sqlx::{Pool, Sqlite};
|
||||||
use sqlx::migrate::Migrator;
|
use sqlx::migrate::Migrator;
|
||||||
use sqlx::sqlite::SqlitePoolOptions;
|
use sqlx::sqlite::SqlitePoolOptions;
|
||||||
use sqlx::types::{Json, JsonValue};
|
use sqlx::types::Json;
|
||||||
use sqlx::{Pool, Sqlite};
|
use tauri::{AppHandle, Menu, MenuItem, State, Submenu, TitleBarStyle, Window, Wry};
|
||||||
use tauri::regex::Regex;
|
|
||||||
use tauri::{AppHandle, Menu, MenuItem, Runtime, State, Submenu, TitleBarStyle, Window, Wry};
|
|
||||||
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent};
|
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent};
|
||||||
|
use tauri::regex::Regex;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use window_ext::WindowExt;
|
use window_ext::WindowExt;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export function BasicAuth({ requestId, authentication }: Props) {
|
|||||||
label="Password"
|
label="Password"
|
||||||
name="password"
|
name="password"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
type="password"
|
||||||
defaultValue={`${authentication.password}`}
|
defaultValue={`${authentication.password}`}
|
||||||
onChange={(password: string) => {
|
onChange={(password: string) => {
|
||||||
updateRequest.mutate((r) => ({
|
updateRequest.mutate((r) => ({
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export const RequestPane = memo(function RequestPane({ style, fullHeight, classN
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ value: 'params', label: 'URL Params' },
|
// { value: 'params', label: 'URL Params' },
|
||||||
{ value: 'headers', label: 'Headers' },
|
{ value: 'headers', label: 'Headers' },
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
|||||||
}
|
}
|
||||||
rightSlot={
|
rightSlot={
|
||||||
<IconButton
|
<IconButton
|
||||||
size="xs"
|
size="sm"
|
||||||
title="Send Request"
|
title="Send Request"
|
||||||
type="submit"
|
type="submit"
|
||||||
color="custom"
|
color="custom"
|
||||||
|
|||||||
@@ -98,6 +98,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Obscure text for password fields */
|
||||||
|
.cm-wrapper.cm-obscure-text .cm-line {
|
||||||
|
-webkit-text-security: disc;
|
||||||
|
}
|
||||||
|
|
||||||
.cm-editor .cm-gutterElement {
|
.cm-editor .cm-gutterElement {
|
||||||
@apply flex items-center;
|
@apply flex items-center;
|
||||||
transition: color var(--transition-duration);
|
transition: color var(--transition-duration);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/vie
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { EditorView } from 'codemirror';
|
import { EditorView } from 'codemirror';
|
||||||
import type { MutableRefObject } from 'react';
|
import type { MutableRefObject } from 'react';
|
||||||
import { useEffect, useMemo, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { IconButton } from '../IconButton';
|
import { IconButton } from '../IconButton';
|
||||||
import './Editor.css';
|
import './Editor.css';
|
||||||
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
|
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
|
||||||
@@ -15,6 +15,7 @@ import { singleLineExt } from './singleLine';
|
|||||||
export interface _EditorProps {
|
export interface _EditorProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
|
type?: 'text' | 'password';
|
||||||
className?: string;
|
className?: string;
|
||||||
heightMode?: 'auto' | 'full';
|
heightMode?: 'auto' | 'full';
|
||||||
contentType?: string;
|
contentType?: string;
|
||||||
@@ -33,6 +34,7 @@ export interface _EditorProps {
|
|||||||
|
|
||||||
export function _Editor({
|
export function _Editor({
|
||||||
readOnly,
|
readOnly,
|
||||||
|
type = 'text',
|
||||||
heightMode,
|
heightMode,
|
||||||
contentType,
|
contentType,
|
||||||
autoFocus,
|
autoFocus,
|
||||||
@@ -117,21 +119,18 @@ export function _Editor({
|
|||||||
};
|
};
|
||||||
}, [wrapperRef.current, languageExtension]);
|
}, [wrapperRef.current, languageExtension]);
|
||||||
|
|
||||||
const cmContainer = useMemo(
|
const cmContainer = (
|
||||||
() => (
|
<div
|
||||||
<div
|
ref={wrapperRef}
|
||||||
ref={wrapperRef}
|
className={classnames(
|
||||||
dangerouslySetInnerHTML={{ __html: '' }}
|
className,
|
||||||
className={classnames(
|
'cm-wrapper text-base bg-gray-50',
|
||||||
className,
|
type === 'password' && 'cm-obscure-text',
|
||||||
'cm-wrapper text-base bg-gray-50',
|
heightMode === 'auto' ? 'cm-auto-height' : 'cm-full-height',
|
||||||
heightMode === 'auto' ? 'cm-auto-height' : 'cm-full-height',
|
singleLine ? 'cm-singleline' : 'cm-multiline',
|
||||||
singleLine ? 'cm-singleline' : 'cm-multiline',
|
readOnly && 'cm-readonly',
|
||||||
readOnly && 'cm-readonly',
|
)}
|
||||||
)}
|
/>
|
||||||
/>
|
|
||||||
),
|
|
||||||
[],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (singleLine) {
|
if (singleLine) {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { LRLanguage } from '@codemirror/language';
|
|||||||
import { parseMixed } from '@lezer/common';
|
import { parseMixed } from '@lezer/common';
|
||||||
import type { GenericCompletionConfig } from '../genericCompletion';
|
import type { GenericCompletionConfig } from '../genericCompletion';
|
||||||
import { genericCompletion } from '../genericCompletion';
|
import { genericCompletion } from '../genericCompletion';
|
||||||
|
import { placeholders } from '../placeholder';
|
||||||
import { textLanguageName } from '../text/extension';
|
import { textLanguageName } from '../text/extension';
|
||||||
import { placeholders } from '../widgets';
|
|
||||||
import { completions } from './completion';
|
import { completions } from './completion';
|
||||||
import { parser as twigParser } from './twig';
|
import { parser as twigParser } from './twig';
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
DotsHorizontalIcon,
|
DotsHorizontalIcon,
|
||||||
DotsVerticalIcon,
|
DotsVerticalIcon,
|
||||||
DragHandleDots2Icon,
|
DragHandleDots2Icon,
|
||||||
|
EyeClosedIcon,
|
||||||
EyeOpenIcon,
|
EyeOpenIcon,
|
||||||
GearIcon,
|
GearIcon,
|
||||||
HamburgerMenuIcon,
|
HamburgerMenuIcon,
|
||||||
@@ -33,10 +34,10 @@ import {
|
|||||||
TriangleRightIcon,
|
TriangleRightIcon,
|
||||||
UpdateIcon,
|
UpdateIcon,
|
||||||
} from '@radix-ui/react-icons';
|
} from '@radix-ui/react-icons';
|
||||||
import { ReactComponent as LeftPanelHiddenIcon } from '../../assets/icons/LeftPanelHiddenIcon.svg';
|
|
||||||
import { ReactComponent as LeftPanelVisibleIcon } from '../../assets/icons/LeftPanelVisibleIcon.svg';
|
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
import { ReactComponent as LeftPanelHiddenIcon } from '../../assets/icons/LeftPanelHiddenIcon.svg';
|
||||||
|
import { ReactComponent as LeftPanelVisibleIcon } from '../../assets/icons/LeftPanelVisibleIcon.svg';
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
archive: ArchiveIcon,
|
archive: ArchiveIcon,
|
||||||
@@ -53,6 +54,7 @@ const icons = {
|
|||||||
dotsV: DotsVerticalIcon,
|
dotsV: DotsVerticalIcon,
|
||||||
drag: DragHandleDots2Icon,
|
drag: DragHandleDots2Icon,
|
||||||
eye: EyeOpenIcon,
|
eye: EyeOpenIcon,
|
||||||
|
eyeClosed: EyeClosedIcon,
|
||||||
gear: GearIcon,
|
gear: GearIcon,
|
||||||
hamburger: HamburgerMenuIcon,
|
hamburger: HamburgerMenuIcon,
|
||||||
home: HomeIcon,
|
home: HomeIcon,
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ const _IconButton = forwardRef<HTMLButtonElement, Props>(function IconButton(
|
|||||||
'!px-0',
|
'!px-0',
|
||||||
size === 'md' && 'w-9',
|
size === 'md' && 'w-9',
|
||||||
size === 'sm' && 'w-8',
|
size === 'sm' && 'w-8',
|
||||||
|
size === 'xs' && 'w-7',
|
||||||
)}
|
)}
|
||||||
size={size}
|
size={size}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ import type { HTMLAttributes, ReactNode } from 'react';
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import type { EditorProps } from './Editor';
|
import type { EditorProps } from './Editor';
|
||||||
import { Editor } from './Editor';
|
import { Editor } from './Editor';
|
||||||
|
import { IconButton } from './IconButton';
|
||||||
import { HStack, VStack } from './Stacks';
|
import { HStack, VStack } from './Stacks';
|
||||||
|
|
||||||
export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'onFocus'> &
|
export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'onFocus'> &
|
||||||
Pick<EditorProps, 'contentType' | 'useTemplating' | 'autocomplete'> & {
|
Pick<EditorProps, 'contentType' | 'useTemplating' | 'autocomplete'> & {
|
||||||
name: string;
|
name: string;
|
||||||
|
type?: 'text' | 'password';
|
||||||
label: string;
|
label: string;
|
||||||
hideLabel?: boolean;
|
hideLabel?: boolean;
|
||||||
labelClassName?: string;
|
labelClassName?: string;
|
||||||
@@ -27,6 +29,7 @@ export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'on
|
|||||||
|
|
||||||
export function Input({
|
export function Input({
|
||||||
label,
|
label,
|
||||||
|
type = 'text',
|
||||||
hideLabel,
|
hideLabel,
|
||||||
className,
|
className,
|
||||||
containerClassName,
|
containerClassName,
|
||||||
@@ -42,6 +45,7 @@ export function Input({
|
|||||||
require,
|
require,
|
||||||
...props
|
...props
|
||||||
}: InputProps) {
|
}: InputProps) {
|
||||||
|
const [obscured, setObscured] = useState(type === 'password');
|
||||||
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
|
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
|
||||||
const id = `input-${name}`;
|
const id = `input-${name}`;
|
||||||
const inputClassName = classnames(
|
const inputClassName = classnames(
|
||||||
@@ -90,12 +94,23 @@ export function Input({
|
|||||||
<Editor
|
<Editor
|
||||||
id={id}
|
id={id}
|
||||||
singleLine
|
singleLine
|
||||||
|
type={type === 'password' && !obscured ? 'text' : type}
|
||||||
defaultValue={defaultValue}
|
defaultValue={defaultValue}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={inputClassName}
|
className={inputClassName}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
{type === 'password' && (
|
||||||
|
<IconButton
|
||||||
|
title={obscured ? `Show ${label}` : `Obscure ${label}`}
|
||||||
|
size="xs"
|
||||||
|
className="mr-0.5"
|
||||||
|
iconSize="sm"
|
||||||
|
icon={obscured ? 'eyeClosed' : 'eye'}
|
||||||
|
onClick={() => setObscured((o) => !o)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{rightSlot}
|
{rightSlot}
|
||||||
</HStack>
|
</HStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
|
|||||||
@@ -101,7 +101,10 @@ export function Tabs({
|
|||||||
{option && 'shortLabel' in option
|
{option && 'shortLabel' in option
|
||||||
? option.shortLabel
|
? option.shortLabel
|
||||||
: option?.label ?? 'Unknown'}
|
: option?.label ?? 'Unknown'}
|
||||||
<Icon icon="triangleDown" className="-mr-1.5" />
|
<Icon
|
||||||
|
icon="triangleDown"
|
||||||
|
className={classnames('-mr-1.5', isActive ? 'opacity-100' : 'opacity-20')}
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</RadioDropdown>
|
</RadioDropdown>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user