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