Skip to content

Commit

Permalink
Merge pull request #199 from medyo/develop
Browse files Browse the repository at this point in the history
[WIP] New Version #Minor
  • Loading branch information
medyo authored May 13, 2024
2 parents 95f6017 + 7be604a commit d187b12
Show file tree
Hide file tree
Showing 18 changed files with 294 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"react-dom": "^17.0.1",
"react-easy-sort": "^1.5.1",
"react-error-boundary": "^3.1.4",
"react-icons": "^4.12.0",
"react-icons": "^5.2.1",
"react-markdown": "^7.0.1",
"react-modal": "^3.12.1",
"react-router-dom": "^6.21.0",
Expand Down
22 changes: 19 additions & 3 deletions src/assets/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -886,19 +886,35 @@ Producthunt item
order: 3;
transition: opacity 0.3s ease-out, transform 0.3s ease-out, visibility 0.3s ease-out;
width: 100%;
display: flex;
align-items: center;
}

.dark .themeAdaptiveFillColor {
fill: white;
filter: invert(1);
}

.searchBarIcon {
position: absolute;
height: 40px;
margin: 0 16px;
width: 24px;
}

text-align: center;
background: white;
border-radius: 50%;
width: 22px;
height: 22px;
padding: 2px;
color: var(--tag-background-color);
}
/*.searchBarIcon > svg {
background-color: white;
color: black;
padding: 2px;
border-radius: 50%;
width: 20px;
height: 20px;
}*/
.searchBarInput {
border-radius: 50px;
color: var(--primary-text-color);
Expand Down
1 change: 1 addition & 0 deletions src/assets/chatgpt_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/assets/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ html.dark {
--chip-text: #fff;
--chip-active-background: #0366d6;
--chip-active-text: #fff;
--chip-delete-button-color: #fff;

/* Step */
--step-normal-background-color: none;
Expand Down Expand Up @@ -155,7 +156,7 @@ html.light {
--chip-border-color: #e7eff7;
--chip-active-background: #0366d6;
--chip-active-text: #fff;

--chip-delete-button-color: #3c5065;
/* Step */
--step-normal-background-color: white;
--step-normal-border-color: #cdd3db;
Expand Down
22 changes: 17 additions & 5 deletions src/components/Elements/ChipsSet/ChipsSet.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import clsx from 'clsx'
import { useState } from 'react'
import { IoIosClose } from 'react-icons/io'
import { Option } from 'src/types'
import './chipset.css'
type ChipProps = {
option: Option
onSelect: (option: Option) => void
onRemove?: (option: Option) => void
active: boolean
}

const Chip = ({ option, onSelect, active = false }: ChipProps) => {
const Chip = ({ option, onSelect, onRemove, active = false }: ChipProps) => {
return (
<button className={'chip ' + (active && 'active')} onClick={() => onSelect(option)}>
{option.icon && <span className="chipIcon">{option.icon}</span>}
{option.label}
</button>
<div className={'chip ' + (active && 'active')}>
<button onClick={() => onSelect(option)}>
{option.icon && <span className="chipIcon">{option.icon}</span>}
{option.label}
</button>
{option.removeable && onRemove && (
<button className="deleteButton" onClick={() => onRemove(option)}>
<IoIosClose className="icon" />
</button>
)}
</div>
)
}
type ChangeAction = {
Expand All @@ -26,13 +35,15 @@ type ChipsSetProps = {
defaultValues?: string[]
canSelectMultiple?: boolean
onChange?: (changes: ChangeAction, options: Option[]) => void
onRemove?: (option: Option) => void
}

export const ChipsSet = ({
className,
options,
canSelectMultiple = false,
onChange,
onRemove,
defaultValues,
}: ChipsSetProps) => {
const [selectedChips, setSelectedChips] = useState<string[] | undefined>(defaultValues || [])
Expand Down Expand Up @@ -80,6 +91,7 @@ export const ChipsSet = ({
key={option.value}
option={option}
onSelect={onSelect}
onRemove={onRemove}
active={selectedChips?.some((chipValue) => chipValue === option.value) || false}
/>
)
Expand Down
25 changes: 23 additions & 2 deletions src/components/Elements/ChipsSet/chipset.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,27 @@
padding: 6px 12px;
border: transparent;
font-family: 'nunito';
color: var(--chip-text);
background-color: var(--chip-background);
display: flex;
align-items: center;
column-gap: 2px;
cursor: pointer;
}
.chip button {
color: var(--chip-text);
border: transparent;
background: none;
display: flex;
align-items: center;
column-gap: 8px;
cursor: pointer;
padding: 0;
margin: 0;
}
.chip .deleteButton .icon {
width: 20px;
height: 20px;
color: var(--chip-delete-button-color);
}
.chip:hover {
filter: brightness(95%);
Expand All @@ -31,13 +46,17 @@
.chip .chipIcon > svg {
background-color: white;
color: black;
border-radius: 50px;
padding: 2px;
border-radius: 50%;
width: 20px;
height: 20px;
}
.chip.active {
background-color: var(--chip-active-background);
}

.chip.active button,
.chip.active .deleteButton .icon {
color: var(--chip-active-text);
}

Expand All @@ -46,5 +65,7 @@
}
.chipsSet.alternative-color .chip.active {
background-color: var(--card-active-action-button-background);
}
.chipsSet.alternative-color .chip.active button {
color: var(--card-active-action-button-color);
}
23 changes: 16 additions & 7 deletions src/components/Elements/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import React, { useEffect, useRef } from 'react'
import { SUPPORTED_SEARCH_ENGINES } from 'src/config'
import { IoSearchCircleSharp } from 'react-icons/io5'
import { trackSearchEngineUse } from 'src/lib/analytics'
import { useUserPreferences } from 'src/stores/preferences'
import { SearchEngine } from 'src/types'

export const SearchBar = () => {
const { searchEngine } = useUserPreferences()
const { searchEngine, searchEngines } = useUserPreferences()

const keywordsInputRef = useRef<HTMLInputElement | null>(null)
const usedSearchEngine: SearchEngine =
SUPPORTED_SEARCH_ENGINES.find((engine) => engine.label === searchEngine) ||
SUPPORTED_SEARCH_ENGINES[0]
const usedSearchEngine =
searchEngines.find((engine) => engine.label === searchEngine) || searchEngines[0]

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
Expand All @@ -28,7 +26,18 @@ export const SearchBar = () => {

return (
<form className="searchBar" onSubmit={handleSubmit}>
<usedSearchEngine.logo className={'searchBarIcon ' + usedSearchEngine.className} />
{usedSearchEngine.default === false ? (
<IoSearchCircleSharp className="searchBarIcon" />
) : (
<img
className={'searchBarIcon'}
src={`src/assets/${usedSearchEngine.label.toLowerCase()}_logo.svg`}
onError={({ currentTarget }) => {
currentTarget.onerror = null
currentTarget.src = `src/assets/search_logo.svg`
}}
/>
)}
<input
ref={keywordsInputRef}
type="text"
Expand Down
21 changes: 14 additions & 7 deletions src/components/Elements/SearchBarWithLogo/SearchBarWithLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import { SUPPORTED_SEARCH_ENGINES } from 'src/config'
import { IoIosSearch } from 'react-icons/io'
import { useUserPreferences } from 'src/stores/preferences'
import { SearchBar } from '../SearchBar/SearchBar'
import './SearchBarWithLogo.css'

export const SearchBarWithLogo = () => {
const { searchEngine } = useUserPreferences()
const userSearchEngine = SUPPORTED_SEARCH_ENGINES.find(
(srchEngn) => srchEngn.label.toLocaleLowerCase() === searchEngine.toLocaleLowerCase()
)
const { searchEngine, searchEngines } = useUserPreferences()
const userSearchEngine =
searchEngines.find(
(srchEngn) => srchEngn.label.toLocaleLowerCase() === searchEngine.toLocaleLowerCase()
) || searchEngines[0]

return (
<div className="searchBarWithLogo">
{userSearchEngine?.logo && (
{userSearchEngine.default === false ? (
<div className="searchEngineLogo">
<userSearchEngine.logo className={userSearchEngine?.className} />
<IoIosSearch />
</div>
) : (
<img
className={'searchEngineLogo ' + userSearchEngine.className}
src={`src/assets/${userSearchEngine.label.toLowerCase()}_logo.svg`}
/>
)}

<SearchBar />
</div>
)
Expand Down
5 changes: 4 additions & 1 deletion src/components/Layout/SettingsLayout/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export const SettingsLayout = () => {
name: 'Bookmarks',
path: '/settings/bookmarks',
},

{
name: 'Search Engine',
path: '/settings/search-engine',
},
{
name: 'Settings',
path: '/settings/general',
Expand Down
61 changes: 61 additions & 0 deletions src/features/settings/components/AddSearchEngine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useState } from 'react'
import { isValidURL } from 'src/utils/UrlUtils'

import { TiPlus } from 'react-icons/ti'
import { useUserPreferences } from 'src/stores/preferences'

export const AddSearchEngine = () => {
const { addSearchEngine, searchEngines } = useUserPreferences()
const [searchEngineUrl, setSearchEngineUrl] = useState<string | undefined>()
const [RssInputFeedback, setRssInputFeedback] = useState<string | undefined>()

const onAddSearchEngine = async () => {
if (!searchEngineUrl) {
setRssInputFeedback('Please provide a valid Search engine URL')
return
}

if (!isValidURL(searchEngineUrl)) {
setRssInputFeedback('Invalid Search Engine URL. Please check and try again')
return
}

if (searchEngines.some((se) => se.url === searchEngineUrl)) {
setRssInputFeedback('Search Engine already exists')
return
}

// Get label from url
const url = new URL(searchEngineUrl)
const label = url.hostname.replace('www.', '').split('.')[0]

addSearchEngine({ label: label, url: searchEngineUrl, default: false })
setRssInputFeedback('Search Engine added successfully')
}

return (
<div className="settingRow">
<p className="settingTitle">Search Engine URL</p>
<div className="settingContent">
<div className="form">
<input
type="text"
value={searchEngineUrl || ''}
onChange={(e) => setSearchEngineUrl(e.target.value)}
placeholder="https://google.com?q="
/>
<div>
<button onClick={onAddSearchEngine}>
<TiPlus /> Add
</button>
</div>
</div>
{RssInputFeedback && (
<div className="settingHint">
<p>{RssInputFeedback}</p>
</div>
)}
</div>
</div>
)
}
Loading

0 comments on commit d187b12

Please sign in to comment.