Obscure text

This commit is contained in:
Gregory Schier
2023-03-29 10:16:51 -07:00
parent 0f58986b4c
commit cd5ae6691c
12 changed files with 54 additions and 29 deletions

View File

@@ -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;

View File

@@ -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) => ({

View File

@@ -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' },
],
[

View File

@@ -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"

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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';

View File

@@ -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,

View File

@@ -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}

View File

@@ -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>

View File

@@ -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>
);