Name fixes, more output formats, algo changes
This commit is contained in:
@ -1,10 +1,12 @@
|
||||
import React, { useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { ColorScheme } from '../utils/colorSchemes';
|
||||
import { generateYAML, generateJSON, generateXResources, generateTOML } from '../utils/exportFormats';
|
||||
import { generateYAML, generateJSON, generateXResources, generateTOML, generateITerm2, generateWindowsTerminal, generateTerminalApp } from '../utils/exportFormats';
|
||||
import { Highlight, themes } from 'prism-react-renderer';
|
||||
import { motion, useAnimation } from 'framer-motion';
|
||||
import ColorPalette from './ColorPalette';
|
||||
import confetti from 'canvas-confetti';
|
||||
import { AppSettings } from '../utils/types';
|
||||
|
||||
interface ColorSchemeCardProps {
|
||||
scheme: ColorScheme;
|
||||
@ -12,16 +14,42 @@ interface ColorSchemeCardProps {
|
||||
onDislike: () => void;
|
||||
index: number;
|
||||
isDarkMode: boolean;
|
||||
codeSample: string;
|
||||
outputFormat: string;
|
||||
settings: AppSettings;
|
||||
}
|
||||
|
||||
const ColorSchemeCard: React.FC<ColorSchemeCardProps> = ({ scheme, onLike, onDislike, index, isDarkMode, codeSample, outputFormat }) => {
|
||||
const ColorSchemeCard: React.FC<ColorSchemeCardProps> = ({ scheme, onLike, onDislike, index, isDarkMode, settings }) => {
|
||||
const [overlayColor, setOverlayColor] = useState('rgba(0, 0, 0, 0)');
|
||||
const controls = useAnimation();
|
||||
|
||||
const getCodeExample = () => {
|
||||
// Add code samples for each language here
|
||||
if (settings.juniorDevMode) {
|
||||
return `
|
||||
// This code is perfect, no need to review
|
||||
function makeItWork() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function does everything
|
||||
function doEverything() {
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
// Ignore this, it's probably not important
|
||||
try {
|
||||
somethingRisky();
|
||||
} catch (e) {
|
||||
// This will never happen
|
||||
}
|
||||
|
||||
// Copy-pasted from StackOverflow
|
||||
const regex = /^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/;
|
||||
|
||||
// I'll fix this later
|
||||
while (true) {
|
||||
// Infinite loop for extra performance
|
||||
}
|
||||
`;
|
||||
}
|
||||
const samples = {
|
||||
c: `#include <stdio.h>
|
||||
|
||||
@ -149,31 +177,30 @@ func main() {
|
||||
num := 7
|
||||
fmt.Printf("Is %d prime? %v\n", num, isPrime(num))
|
||||
}`,
|
||||
javascript: `function isPrime(n) {
|
||||
if (n <= 1) return false;
|
||||
for (let i = 2; i <= Math.sqrt(n); i++) {
|
||||
if (n % i === 0) return false;
|
||||
}
|
||||
return true;
|
||||
javascript: `/* Calculate the area and circumference of a circle */
|
||||
const pi = 3.14;
|
||||
|
||||
function calculateArea(r) {
|
||||
return pi * r ** 2; // Exponentiation, constant, operator
|
||||
}
|
||||
|
||||
function primesUpTo(limit) {
|
||||
let primes = [];
|
||||
for (let i = 2; i <= limit; i++) {
|
||||
if (isPrime(i)) primes.push(i);
|
||||
}
|
||||
return primes;
|
||||
function calculateCircumference(r) {
|
||||
return 2 * pi * r; // Function, return, operators
|
||||
}
|
||||
|
||||
function fibonacci(n) {
|
||||
let fib = [0, 1];
|
||||
for (let i = 2; i < n; i++) {
|
||||
fib.push(fib[i - 1] + fib[i - 2]);
|
||||
}
|
||||
return fib;
|
||||
if (radius > 0) {
|
||||
console.log(\`Area: $\{calculateArea(radius)\}\`); // Template string, method
|
||||
console.log(\`Circumference: $\{calculateCircumference(radius)\}\`);
|
||||
} else {
|
||||
console.error("Invalid radius!"); // Error handling
|
||||
}
|
||||
|
||||
let limit = 50;`,
|
||||
try {
|
||||
radius = -1;
|
||||
if (radius < 0) throw new Error("Negative radius"); // Throw, error
|
||||
} catch (e) {
|
||||
console.warn(e.message); // Catch block, method
|
||||
}`,
|
||||
bash: `#!/bin/bash
|
||||
|
||||
is_prime() {
|
||||
@ -219,7 +246,7 @@ fi`
|
||||
return sample in samples;
|
||||
};
|
||||
|
||||
return isValidSample(codeSample) ? samples[codeSample] : samples.javascript;
|
||||
return isValidSample(settings.codeSample) ? samples[settings.codeSample] : samples.javascript;
|
||||
};
|
||||
|
||||
const handleDownload = (e: React.MouseEvent) => {
|
||||
@ -227,7 +254,7 @@ fi`
|
||||
let content: string;
|
||||
let fileExtension: string;
|
||||
|
||||
switch (outputFormat) {
|
||||
switch (settings.outputFormat) {
|
||||
case 'json':
|
||||
content = generateJSON(scheme);
|
||||
fileExtension = 'json';
|
||||
@ -240,6 +267,18 @@ fi`
|
||||
content = generateTOML(scheme);
|
||||
fileExtension = 'toml';
|
||||
break;
|
||||
case 'iterm2':
|
||||
content = generateITerm2(scheme);
|
||||
fileExtension = 'itermcolors';
|
||||
break;
|
||||
case 'windows-terminal':
|
||||
content = generateWindowsTerminal(scheme);
|
||||
fileExtension = 'json';
|
||||
break;
|
||||
case 'terminal-app':
|
||||
content = generateTerminalApp(scheme);
|
||||
fileExtension = 'terminal';
|
||||
break;
|
||||
case 'yaml':
|
||||
default:
|
||||
content = generateYAML(scheme);
|
||||
@ -259,7 +298,16 @@ fi`
|
||||
|
||||
const handleLike = () => {
|
||||
setOverlayColor('rgba(0, 255, 0, 0.1)');
|
||||
controls.start({ x: 300, opacity: 0, transition: { duration: 0.3 } }).then(onLike);
|
||||
controls.start({ x: 300, opacity: 0, transition: { duration: 0.3 } }).then(() => {
|
||||
if (settings.partyMode) {
|
||||
confetti({
|
||||
particleCount: 100,
|
||||
spread: 70,
|
||||
origin: { y: 0.6 }
|
||||
});
|
||||
}
|
||||
onLike();
|
||||
});
|
||||
};
|
||||
|
||||
const handleDislike = () => {
|
||||
@ -318,7 +366,7 @@ fi`
|
||||
</button>
|
||||
</div>
|
||||
<div className="bg-gray-100 dark:bg-gray-700 rounded-md mb-2 flex-grow overflow-hidden z-10 shadow-md">
|
||||
<Highlight theme={themes.dracula} code={getCodeExample()} language={codeSample}>
|
||||
<Highlight theme={themes.dracula} code={getCodeExample()} language={settings.codeSample}>
|
||||
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
||||
<pre className={`${className} text-sm p-4 h-full overflow-auto`} style={{ ...style, backgroundColor: scheme.colors.primary.background }}>
|
||||
{tokens.map((line, i) => (
|
||||
|
76
app/components/FormatInstructions.tsx
Normal file
76
app/components/FormatInstructions.tsx
Normal file
@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import Image from 'next/image';
|
||||
|
||||
interface FormatInstructionsProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
isDarkMode: boolean;
|
||||
}
|
||||
|
||||
const FormatInstructions: React.FC<FormatInstructionsProps> = ({ isOpen, onClose, isDarkMode }) => {
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-xl w-[90vw] max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<h2 className="text-2xl font-bold">Color Scheme Installation Instructions</h2>
|
||||
<button onClick={onClose} className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
|
||||
<Image src={isDarkMode ? "/close-icon-dark.svg" : "/close-icon-light.svg"} alt="Close" width={24} height={24} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-xl font-semibold">YAML (Alacritty)</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the YAML file.</li>
|
||||
<li>Place it in your Alacritty configuration directory (usually <code>~/.config/alacritty/</code>).</li>
|
||||
<li>In your <code>alacritty.yml</code> file, add: <code>import: [/path/to/your/theme.yml]</code></li>
|
||||
</ol>
|
||||
|
||||
<h3 className="text-xl font-semibold">JSON</h3>
|
||||
<p>JSON format can be used in various terminals. Refer to your terminal's documentation for specific instructions.</p>
|
||||
|
||||
<h3 className="text-xl font-semibold">XResources</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the XResources file.</li>
|
||||
<li>Add the contents to your <code>~/.Xresources</code> file.</li>
|
||||
<li>Run <code>xrdb ~/.Xresources</code> to reload.</li>
|
||||
</ol>
|
||||
|
||||
<h3 className="text-xl font-semibold">TOML (Alacritty)</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the TOML file.</li>
|
||||
<li>Place it in your Alacritty configuration directory.</li>
|
||||
<li>In your <code>alacritty.toml</code> file, add: <code>import = ["/path/to/your/theme.toml"]</code></li>
|
||||
</ol>
|
||||
|
||||
<h3 className="text-xl font-semibold">iTerm2</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the iTerm2 color scheme file.</li>
|
||||
<li>Open iTerm2 preferences.</li>
|
||||
<li>Go to Profiles > Colors.</li>
|
||||
<li>Click on "Color Presets..." and choose "Import..."</li>
|
||||
<li>Select the downloaded file.</li>
|
||||
</ol>
|
||||
|
||||
<h3 className="text-xl font-semibold">Windows Terminal</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the JSON file.</li>
|
||||
<li>Open Windows Terminal settings.</li>
|
||||
<li>In the "schemes" array, add the contents of the downloaded JSON file.</li>
|
||||
<li>In your profile, set "colorScheme" to the name of your new scheme.</li>
|
||||
</ol>
|
||||
|
||||
<h3 className="text-xl font-semibold">Terminal.app (macOS)</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
<li>Download the Terminal.app color scheme file.</li>
|
||||
<li>Double-click the downloaded file to import it into Terminal.app.</li>
|
||||
<li>In Terminal.app preferences, select the imported profile.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormatInstructions;
|
@ -21,6 +21,7 @@ const HelpDialog: React.FC<HelpDialogProps> = ({ isOpen, onClose, isDarkMode })
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<p>Welcome to TerminalTinder, the dating app that actually designed to be used over and over again.</p>
|
||||
<p>The more you interact with TerminalTinder, the better it becomes at suggesting color schemes and even creating new ones.</p>
|
||||
|
||||
<h3 className="text-xl font-semibold">How it works:</h3>
|
||||
<ol className="list-decimal list-inside space-y-2">
|
||||
@ -34,12 +35,12 @@ const HelpDialog: React.FC<HelpDialogProps> = ({ isOpen, onClose, isDarkMode })
|
||||
<ul className="list-disc list-inside space-y-2">
|
||||
<li>View a live preview of the color scheme applied to code.</li>
|
||||
<li>Change the programming language of the preview in the settings.</li>
|
||||
<li>Download color schemes in various formats (YAML, JSON, TOML, Xresources).</li>
|
||||
<li>Download color schemes in various formats (YAML, JSON, TOML, Xresources, and more).</li>
|
||||
<li>View your liked and disliked schemes in the history.</li>
|
||||
</ul>
|
||||
|
||||
<p>The more you interact with TerminalTinder, the better it becomes at suggesting color schemes. All information is local, so refreshing the page refreshes learning.</p>
|
||||
<p>It's your internet, take it back.</p>
|
||||
<hr className="my-4 border-t border-gray-200 w-full" />
|
||||
<p>DWS - It's your internet, take it back.</p>
|
||||
<hr className="my-4 border-t border-gray-200 w-full" />
|
||||
<p>All credit for any non generated color schemes goes to their original creators. Color schemes are sourced from <a href="https://github.com/Mayccoll/Gogh" target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600">Gogh</a>.</p>
|
||||
|
||||
|
@ -1,18 +1,15 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Image from 'next/image';
|
||||
|
||||
// Import the CodeSample type
|
||||
import { CodeSample } from '../utils/types';
|
||||
import { CodeSample, AppSettings } from '../utils/types';
|
||||
import FormatInstructions from './FormatInstructions';
|
||||
|
||||
interface SettingsProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
isDarkMode: boolean;
|
||||
onToggleDarkMode: () => void;
|
||||
outputFormat: string;
|
||||
setOutputFormat: (format: string) => void;
|
||||
codeSample: CodeSample;
|
||||
setCodeSample: (sample: CodeSample) => void;
|
||||
settings: AppSettings;
|
||||
setSettings: (settings: AppSettings) => void;
|
||||
saveSettings: boolean;
|
||||
setSaveSettings: (save: boolean) => void;
|
||||
}
|
||||
@ -22,14 +19,13 @@ const Settings: React.FC<SettingsProps> = ({
|
||||
onClose,
|
||||
isDarkMode,
|
||||
onToggleDarkMode,
|
||||
outputFormat,
|
||||
setOutputFormat,
|
||||
codeSample,
|
||||
setCodeSample,
|
||||
settings,
|
||||
setSettings,
|
||||
saveSettings,
|
||||
setSaveSettings
|
||||
}) => {
|
||||
const [showCookieNotice, setShowCookieNotice] = useState(false);
|
||||
const [showFormatInstructions, setShowFormatInstructions] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (saveSettings && !localStorage.getItem('cookieNoticeShown')) {
|
||||
@ -79,22 +75,33 @@ const Settings: React.FC<SettingsProps> = ({
|
||||
</div>
|
||||
<div>
|
||||
<label className="block mb-2">Output Format</label>
|
||||
<select
|
||||
value={outputFormat}
|
||||
onChange={(e) => setOutputFormat(e.target.value)}
|
||||
className="w-full p-2 border rounded dark:bg-gray-700 dark:border-gray-600"
|
||||
>
|
||||
<option value="json">JSON</option>
|
||||
<option value="xresources">XResources</option>
|
||||
<option value="yaml">YAML (Alacritty)</option>
|
||||
<option value="toml">TOML (Alacritty)</option>
|
||||
</select>
|
||||
<div className="flex items-center">
|
||||
<select
|
||||
value={settings.outputFormat}
|
||||
onChange={(e) => setSettings({ ...settings, outputFormat: e.target.value })}
|
||||
className="w-full p-2 border rounded dark:bg-gray-700 dark:border-gray-600"
|
||||
>
|
||||
<option value="yaml">YAML (Alacritty)</option>
|
||||
<option value="json">JSON</option>
|
||||
<option value="xresources">XResources</option>
|
||||
<option value="toml">TOML (Alacritty)</option>
|
||||
<option value="iterm2">iTerm2</option>
|
||||
<option value="windows-terminal">Windows Terminal</option>
|
||||
<option value="terminal-app">Terminal.app</option>
|
||||
</select>
|
||||
<button
|
||||
onClick={() => setShowFormatInstructions(true)}
|
||||
className="ml-2 text-blue-500 hover:text-blue-600"
|
||||
>
|
||||
<Image src={isDarkMode ? "/question-mark-dark.svg" : "/question-mark-light.svg"} alt="Format Instructions" width={24} height={24} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block mb-2">Code Sample</label>
|
||||
<select
|
||||
value={codeSample}
|
||||
onChange={(e) => setCodeSample(e.target.value as CodeSample)}
|
||||
value={settings.codeSample}
|
||||
onChange={(e) => setSettings({ ...settings, codeSample: e.target.value as CodeSample })}
|
||||
className="w-full p-2 border rounded dark:bg-gray-700 dark:border-gray-600"
|
||||
>
|
||||
<option value="c">C</option>
|
||||
@ -116,6 +123,36 @@ const Settings: React.FC<SettingsProps> = ({
|
||||
/>
|
||||
<label htmlFor="saveSettings">Save settings in cookie</label>
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<span>Junior Dev Mode</span>
|
||||
<button
|
||||
onClick={() => setSettings({ ...settings, juniorDevMode: !settings.juniorDevMode })}
|
||||
className={`w-12 h-6 rounded-full p-1 transition-colors duration-300 ease-in-out ${
|
||||
settings.juniorDevMode ? 'bg-blue-600' : 'bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`w-4 h-4 rounded-full bg-white transform transition-transform duration-300 ease-in-out ${
|
||||
settings.juniorDevMode ? 'translate-x-6' : ''
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<span>Party Mode</span>
|
||||
<button
|
||||
onClick={() => setSettings({ ...settings, partyMode: !settings.partyMode })}
|
||||
className={`w-12 h-6 rounded-full p-1 transition-colors duration-300 ease-in-out ${
|
||||
settings.partyMode ? 'bg-blue-600' : 'bg-gray-300'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`w-4 h-4 rounded-full bg-white transform transition-transform duration-300 ease-in-out ${
|
||||
settings.partyMode ? 'translate-x-6' : ''
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{showCookieNotice && (
|
||||
@ -126,6 +163,11 @@ const Settings: React.FC<SettingsProps> = ({
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<FormatInstructions
|
||||
isOpen={showFormatInstructions}
|
||||
onClose={() => setShowFormatInstructions(false)}
|
||||
isDarkMode={isDarkMode}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user