Skip to content

Commit

Permalink
Autocomplete and Filter Cycling (#27)
Browse files Browse the repository at this point in the history
* Initial autocomplete rework
* Fix clear prompt glitch
* Add command autocomplete
* Add initial filter cycling through TAB key
* Add basic filter cycling functionality
* Improve filter cycling and autocomplete
* Add config help to autocomplete
* Bump version to v2.3.0
* Improve config help output with colors
* Remove editor line highlight
* Update README.md gif
* Add theme names to autocomplete
  • Loading branch information
excalith authored Apr 13, 2023
1 parent dc4eb55 commit 46cef8c
Show file tree
Hide file tree
Showing 22 changed files with 331 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ In order to contribute to the source of the project
I really appreciate contributions in the form of new themes to the project. If you'd like to add a new theme, please follow these steps:

1. Create a new `json` file in the `public/themes` folder using the theme name as the file name. Please use `kebab-case` for the file name. You can use the default theme file as a starting point.
2. Add the theme name to the array in the `public/themes.json` file. Please use the same name as the file and use alphabetical order.
2. Add the theme name to the array in the `src/utils/themes.js` file. Please use the same name as the file and use alphabetical order.
3. Test your theme by running the project locally by running `yarn dev` command
1. Use `set theme` command to see your theme on the list
2. Use `set theme <theme-name>` to see your theme in action
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ labels: ''
assignees: excalith

---
<!-- Please read contributing guideline first -->

**Describe the bug**
A clear and concise description of what the bug is.
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ labels: enhancement
assignees: excalith

---
<!-- Please read contributing guideline first -->

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Expand Down
Binary file modified .github/startpage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
All upcoming and notable changes to this project will be documented in this file.

> **Warning**
> Before updating, please be sure to check versions for possible **breaking changes**. If you are using preview version (online) and have issues, please check out the [troubleshooting](https://github.com/excalith/excalith-start-page/wiki/Troubleshooting) page how to fix it and learn why you shouldn't use preview version.
> Before updating, please be sure to check previous versions for possible **breaking changes**. If you are using preview (online) version and having issues, please refer to [troubleshooting](https://github.com/excalith/excalith-start-page/wiki/Troubleshooting) page to find possible solutions and learn why you shouldn't use preview version.
## Unreleased

### Added
- Error handling for client-side issues by showing possible solutions.
- Using <kbd>→</kbd> auto-completes the suggestion if any. (#25)
- Using <kbd>TAB</kbd> and <kbd>SHIFT</kbd> + <kbd> TAB</kbd> cycles through filtered links. (#25)

### Improved
- `Prompt` and `Search` component layouts
- `help` output with keybindings
- Colorized `config help` output

## Previous Versions [![Latest Release](https://img.shields.io/github/v/release/excalith/excalith-start-page)](https://github.com/excalith/excalith-start-page/releases)

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ You can check the working version from [here](https://excalith-start-page.vercel
- Search websites with custom commands. For example, type `s some weird bug` to search StackOverflow for `some weird bug`
- Wallpaper support through URL with blur and fade effects
- Customizable Fetch UI for fetching browser and system data, including custom image support
- Autosuggest and Autocomplete support just like `zsh` and `fish`
- Cycle through filtered links back and forth
- Multiple theme support (check all [available themes](./public/themes/))
- Built-in configuration editor to easily edit and save your configuration

Expand All @@ -46,8 +48,10 @@ Please refer to [configuration](https://github.com/excalith/excalith-start-page/

### Key Bindings

- Use <kbd>→</kbd> to auto-complete the suggestion
- Cycle through filtered links using <kbd>TAB</kbd> and <kbd>SHIFT</kbd> + <kbd> TAB</kbd>
- Clear the prompt quickly with <kbd>CTRL</kbd> + <kbd>C</kbd>
- Close window with <kbd>ESC</kbd>
- Close windows with <kbd>ESC</kbd>


## Using
Expand Down Expand Up @@ -102,12 +106,12 @@ If you still prefer to use the online version, I would recommend you to use the

## Customization

There are multiple ways of customizing the start page to making it yours! Please refer to [configuration](https://github.com/excalith/excalith-start-page/wiki/Configuration) and [themes](https://github.com/excalith/excalith-start-page/wiki/Themes) pages for more information.
You can pretty much customize everything! Please refer to [configuration](https://github.com/excalith/excalith-start-page/wiki/Configuration) and [themes](https://github.com/excalith/excalith-start-page/wiki/Themes) pages for more information regarding themes and configuration options.

## How To Contribute

Please feel free to contribute any way you can. Just keep in mind that you should pay attention to [contributing guideline](.github/CONTRIBUTING.md) before contributing.

## License

The code is available under the [MIT license](LICENSE).
The code is available under the [MIT license](LICENSE). Feel free to copy, modify, and distribute the code as you wish, but please keep the original license in the files. Attribution is appreciated and will definetely help improving this project.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "start-page",
"version": "2.2.0",
"version": "2.3.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
55 changes: 26 additions & 29 deletions src/components/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import Prompt from "@/components/Prompt"
import { isURL } from "@/utils/isURL"
import { useSettings } from "@/context/settings"
import dynamic from "next/dynamic"
import { themes } from "@/utils/themes"

async function getTheme(themeName) {
async function fetchTheme(themeName) {
try {
const theme = await fetch("/themes/" + themeName + ".json").then((res) => res.json())
return theme
Expand All @@ -13,16 +14,6 @@ async function getTheme(themeName) {
}
}

async function getThemes() {
try {
const themes = await fetch("/themes.json").then((res) => res.json())
return themes
} catch {
console.log("Error fetching themes")
return null
}
}

const Config = ({ commands, closeCallback }) => {
const [command] = useState(commands.join(" "))
const [consoleLog, setConsoleLog] = useState([])
Expand All @@ -46,21 +37,18 @@ const Config = ({ commands, closeCallback }) => {
} else if (cmd === "theme") {
if (commands.length === 3) {
const themeName = commands[2]
getTheme(themeName).then((theme) => {
fetchTheme(themeName).then((theme) => {
if (theme === null) {
invalidTheme(theme)
} else {
setTheme(theme, themeName)
}
})
} else {
getThemes().then((themes) => {
appendToLog("Available themes:", "title")
for (let i in themes) {
appendToLog(themes[i])
}
setDone(true)
themes.map((theme) => {
appendToLog(theme)
})
setDone(true)
}
} else if (cmd === "help") {
usageExample()
Expand Down Expand Up @@ -105,20 +93,20 @@ const Config = ({ commands, closeCallback }) => {

const usageExample = () => {
appendToLog("Usage:", "title")
appendToLog("config help: Show usage examples")
appendToLog("config theme: List available themes")
appendToLog("config theme <theme-name>: Switch theme")
appendToLog("config import <url>: Import remote config")
appendToLog("config edit: Edit local config")
appendToLog("config reset: Reset to default config")
appendToLog(["config help", "Show usage examples"], "help")
appendToLog(["config theme", "List available themes"], "help")
appendToLog(["config theme <theme-name>", "Switch theme"], "help")
appendToLog(["config import <url>", "Import remote config"], "help")
appendToLog(["config edit", "Edit local config"], "help")
appendToLog(["config reset", "Reset to default config"], "help")
setDone(true)
}

const invalidTheme = (themeName) => {
appendToLog("Invalid theme: " + commands[2], "error")
appendToLog("Usage:", "title")
appendToLog("config theme: Show available themes")
appendToLog("config theme <theme>: Set theme")
appendToLog(["config theme", "Show available themes"], "help")
appendToLog(["config theme <theme>", "Set theme"], "help")
setDone(true)
}

Expand Down Expand Up @@ -146,8 +134,7 @@ const Config = ({ commands, closeCallback }) => {
<div className="row">
<ul className="list-none">
<li>
<Prompt />
{command}
<Prompt command={command} />
</li>
</ul>
{isEditMode ? (
Expand All @@ -174,11 +161,21 @@ const Config = ({ commands, closeCallback }) => {
{data.type === "title" && (
<p className="text-green">{data.text}</p>
)}
{data.type === "help" && (
<p>
<span className="text-blue">{data.text[0]}</span>{" "}
{data.text[1]}
</p>
)}
{data.type === undefined && <p>{data.text}</p>}
</li>
)
})}
{isDone && <li className="mt-line">Press ESC to continue...</li>}
{isDone && (
<li className="mt-line">
Press <span className="text-blue">ESC</span> to continue...
</li>
)}
</ul>
)}
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/components/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ const Editor = () => {
setOptions={{
showLineNumbers: true,
tabSize: 2,
useWorker: false
useWorker: false,
highlightActiveLine: false,
highlightSelectedWord: false,
highlightGutterLine: false
}}
ref={editor}
/>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ const Fetch = ({ closeCallback }) => {
<div className="mx-auto">
<div className="row">
<Prompt showSymbol={false} />
<span className="float-right text-gray">v{fetchData.version}</span>
<span className="absolute float-right -mt-line right-3 text-gray">
v{fetchData.version}
</span>
<hr className="border-dashed" />
<ul className="mt-2">
{settings.fetch.data.map((item, index) => {
Expand Down
25 changes: 21 additions & 4 deletions src/components/Help.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,23 @@ const Help = ({ closeCallback }) => {
<li>- Filter links by typing in the prompt</li>
<li>- Unfiltered prompt will search using default search engine</li>
<li>- Launch URL's directly from prompt</li>
<li>- Use CTRL+C to clear prompt</li>
<li>- Use ESC to exit windows</li>
</ul>

<span className="block mt-line text-green">Key Bindings</span>
<ul>
<li>
- Use <span className="text-blue"></span> key to complete suggestion
</li>
<li>
- Use <span className="text-blue">TAB</span> and{" "}
<span className="text-blue">SHIFT+TAB</span> to cycle through filtered links
</li>
<li>
- Use <span className="text-blue">CTRL+C</span> to clear prompt
</li>
<li>
- Use <span className="text-blue">ESC</span> to exit windows
</li>
</ul>

<span className="block mt-line text-green">Built-in Commands</span>
Expand Down Expand Up @@ -58,7 +73,7 @@ const Help = ({ closeCallback }) => {
</li>
</ul>

<span className="block mt-line text-green">Custom Commands</span>
<span className="block mt-line text-green">Search Aliases</span>
<ul>
{settings.search.shortcuts.map((cmd, index) => {
return (
Expand All @@ -69,7 +84,9 @@ const Help = ({ closeCallback }) => {
})}
</ul>
<ul>
<li className="my-line">Press ESC to continue...</li>
<li className="my-line">
Press <span className="text-blue">ESC</span> to continue...
</li>
</ul>
</div>
</div>
Expand Down
35 changes: 22 additions & 13 deletions src/components/Link.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useEffect, useState } from "react"
import { Icon } from "@iconify/react"

const Link = ({ linkData, filter }) => {
const Link = ({ linkData, filter, selection }) => {
const [isHidden, setHidden] = useState(false)
const [isSelected, setSelected] = useState(false)

const name = linkData.name
const lower_name = linkData.name.toLowerCase()
Expand All @@ -14,25 +15,33 @@ const Link = ({ linkData, filter }) => {
const lower_command = filter.toLowerCase()

if (lower_command) {
const isSelected = lower_name.includes(lower_command)
setHidden(!isSelected)
const isFiltered = lower_name.startsWith(lower_command)
setHidden(!isFiltered)
} else {
setHidden(false)
}
}, [filter, lower_name, target, url]),
[filter]

useEffect(() => {
setSelected(lower_name === selection)
}, [selection])

return (
<a
className={`block ${isHidden && "opacity-20"}`}
href={url}
rel="noopener noreferrer nofollow"
target={target}>
<span className="inline-block w-4 h-4 align-middle">
<Icon icon={icon} />
</span>
<span className="inline-block pl-2 font-light leading-8 align-middle">{name}</span>
</a>
<li className="-my-2 -ml-3">
<a
className={`ml-2 leading-2 my-1 ${isHidden && "opacity-20"} ${
isSelected ? "selected" : ""
} inline-block px-1 rounded-selection`}
href={url}
rel="noopener noreferrer nofollow"
target={target}>
<span className="inline-block w-4 h-4 align-middle">
<Icon icon={icon} />
</span>
<span className="inline-block pl-2 font-light leading-8 align-middle">{name}</span>
</a>
</li>
)
}

Expand Down
65 changes: 65 additions & 0 deletions src/components/List.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { use, useEffect, useState } from "react"
import Link from "@/components/Link"
import Search from "@/components/Search"
import { useSettings } from "@/context/settings"

const Section = ({ section, filter, selection }) => {
const alignment = section.align || "left"
return (
<div className={`mb-4 align-${alignment}`}>
<h2 className={`text-title font-bold mt-0 mb-3 cursor-default text-${section.color}`}>
{section.title}
</h2>

<ul>
{section.links.map((link, index) => {
{
return (
<Link
className="font-normal"
key={index}
linkData={link}
filter={filter}
selection={selection}
/>
)
}
})}
</ul>
</div>
)
}

const List = () => {
const { settings } = useSettings()
const [command, setCommand] = useState("")
const [selection, setSelection] = useState("")

const handleCommandChange = (str) => {
setCommand(str)
}

const handleSelectionChange = (sel) => {
setSelection(sel)
}

return (
<div id="list">
<div className="grid grid-cols-3 gap-4 px-3 py-2 mb-5">
{settings.sections.list.map((section, index) => {
return (
<Section
key={index}
section={section}
filter={command}
selection={selection}
/>
)
})}
</div>
<Search commandChange={handleCommandChange} selectionChange={handleSelectionChange} />
</div>
)
}

export default List
Loading

1 comment on commit 46cef8c

@vercel
Copy link

@vercel vercel bot commented on 46cef8c Apr 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

start-page – ./

start-page-excalith.vercel.app
excalith-start-page.vercel.app
start-page-git-main-excalith.vercel.app

Please sign in to comment.