feat: LEXAI-15 writing style selector in modal, popup, and right-click menu
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 47s
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 47s
This commit is contained in:
@@ -37,6 +37,10 @@ async function safeSendMessage(
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Constants ───────────────────────────────────────────────────────────────
|
||||
|
||||
const WRITING_STYLES = ['Default', 'Formal', 'Casual', 'Academic', 'Creative', 'Concise'];
|
||||
|
||||
// ─── Types ───────────────────────────────────────────────────────────────────
|
||||
|
||||
type Action = 'fix' | 'rephrase' | 'shorten' | 'expand';
|
||||
@@ -97,6 +101,29 @@ const S = {
|
||||
boxSizing: 'border-box' as const,
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
styleRow: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
marginTop: '10px',
|
||||
marginBottom: '2px',
|
||||
},
|
||||
styleLabel: {
|
||||
fontSize: '12px',
|
||||
color: '#a6adc8',
|
||||
flexShrink: 0,
|
||||
},
|
||||
styleSelect: {
|
||||
background: 'rgba(49,50,68,0.95)',
|
||||
border: '1px solid rgba(205,214,244,0.2)',
|
||||
borderRadius: '6px',
|
||||
color: '#cdd6f4',
|
||||
fontSize: '12px',
|
||||
padding: '4px 8px',
|
||||
cursor: 'pointer',
|
||||
flex: 1,
|
||||
outline: 'none',
|
||||
},
|
||||
actionsRow: {
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap' as const,
|
||||
@@ -190,16 +217,20 @@ function Popup() {
|
||||
const [error, setError] = useState('');
|
||||
const [processing, setProcessing] = useState(false);
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [writingStyle, setWritingStyle] = useState('Default');
|
||||
const sessionRestored = useRef(false);
|
||||
|
||||
// Load config + restore session input
|
||||
// Load config + restore session input + load writing style
|
||||
useEffect(() => {
|
||||
safeStorageGet(chrome.storage.local, ['provider', 'apiKey', 'apiKeyEnc', 'model'], (result) => {
|
||||
safeStorageGet(chrome.storage.local, ['provider', 'apiKey', 'apiKeyEnc', 'model', 'writingStyle'], (result) => {
|
||||
if (result.apiKey || result.apiKeyEnc) {
|
||||
setConfigured(true);
|
||||
setProvider(result.provider || 'openai');
|
||||
setModel(result.model || '');
|
||||
}
|
||||
if (result.writingStyle) {
|
||||
setWritingStyle(result.writingStyle);
|
||||
}
|
||||
});
|
||||
|
||||
if (!sessionRestored.current) {
|
||||
@@ -219,6 +250,13 @@ function Popup() {
|
||||
safeStorageSet(chrome.storage.session, { lexai_popup_input: val });
|
||||
};
|
||||
|
||||
// Save writing style on change
|
||||
const handleStyleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const val = e.target.value;
|
||||
setWritingStyle(val);
|
||||
safeStorageSet(chrome.storage.local, { writingStyle: val });
|
||||
};
|
||||
|
||||
const openSettings = () => {
|
||||
try {
|
||||
if (typeof chrome !== 'undefined' && chrome.runtime?.id) {
|
||||
@@ -239,8 +277,7 @@ function Popup() {
|
||||
|
||||
const response = await safeSendMessage({
|
||||
type: 'ANALYZE_TEXT',
|
||||
action,
|
||||
text,
|
||||
payload: { text, action, style: writingStyle },
|
||||
});
|
||||
|
||||
setProcessing(false);
|
||||
@@ -331,6 +368,21 @@ function Popup() {
|
||||
rows={4}
|
||||
/>
|
||||
|
||||
{/* Style selector */}
|
||||
<div style={S.styleRow}>
|
||||
<span style={S.styleLabel}>Style:</span>
|
||||
<select
|
||||
style={S.styleSelect}
|
||||
value={writingStyle}
|
||||
onChange={handleStyleChange}
|
||||
disabled={processing}
|
||||
>
|
||||
{WRITING_STYLES.map(s => (
|
||||
<option key={s} value={s}>{s}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Action buttons */}
|
||||
<div style={S.actionsRow}>
|
||||
{actions.map(({ label, id }) => (
|
||||
|
||||
Reference in New Issue
Block a user