Skip to content

Commit

Permalink
feat: spotlight
Browse files Browse the repository at this point in the history
  • Loading branch information
Renovamen committed May 6, 2021
1 parent 6840eef commit a3c6a44
Show file tree
Hide file tree
Showing 8 changed files with 313 additions and 8 deletions.
264 changes: 264 additions & 0 deletions src/components/Spotlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
import React, { Component } from "react";
import format from "date-fns/format";
import { BiSearch } from "react-icons/bi";
import apps from "../configs/apps";
import launchpad from "../configs/launchpad";

const allApps = {
app: apps,
portfolio: launchpad
};

const getRandom = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
};

function getRandomDate() {
const timeStamp = new Date().getTime();
const randomStamp = getRandom(0, timeStamp);
const date = format(randomStamp, "MM/dd/yyyy");
return date;
}

export default class Spotlight extends Component {
constructor(props) {
super(props);
this.state = {
searchText: "",
curDetails: null,
appList: null
};
this.appIndices = 0;
this.curSelection = 0;
}

search = (type) => {
if (this.state.searchText === "") return [];
const text = this.state.searchText.toLowerCase();
const list = allApps[type].filter((item) => {
return item.title.toLowerCase().substring(0, text.length) === text;
});
return list;
};

renderAppList = (type, startId) => {
const result = this.search(type);
let appList = [];
let curID = startId;

for (let app of result) {
const bg = curID === 0 ? "bg-blue-500" : "bg-transparent";
const text = curID === 0 ? "text-white" : "text-black";

if (curID === 0) {
const curDetails = app;
curDetails.type = type;
this.setState({ curDetails });
}

appList.push(
<li
id={`spotlight-${curID}`}
key={`spotlight-${curID}`}
className={`pl-4 h-7 w-full flex flex-row ${bg} ${text} cursor-default`}
data-app-id={app.id}
data-app-type={type}
>
<div className="flex-none w-8 flex items-center">
<img
className="w-5 mx-auto"
src={app.img}
alt={app.title}
title={app.title}
/>
</div>
<div className="flex-grow flex items-center pl-3">{app.title}</div>
</li>
);

curID += 1;
}
return appList;
};

updateAppList = () => {
const app = this.renderAppList("app", 0);
const portfolio = this.renderAppList("portfolio", app.length);

this.appIndices = app.length + portfolio.length;

const appList = (
<div>
{app.length !== 0 && (
<div>
<div className="pl-6 h-4 text-xs bg-gray-400 bg-opacity-80 flex items-center text-black">
Applications
</div>
<ul className="w-full text-sm">{app}</ul>
</div>
)}
{portfolio.length !== 0 && (
<div>
<div className="pl-6 h-4 text-xs bg-gray-400 bg-opacity-80 flex items-center text-black">
Portfolio
</div>
<ul className="w-full text-sm">{portfolio}</ul>
</div>
)}
</div>
);
this.setState({ appList });
};

getCurDetails = () => {
const elem = document.querySelector(`#spotlight-${this.curSelection}`);
const id = elem.dataset.appId;
const type = elem.dataset.appType;
let curDetails = allApps[type].find((item) => {
return item.id === id;
});
curDetails.type = type;
this.setState({ curDetails });
};

handleHighlight = (cur) => {
// remove highlight
let classes = cur.className;
classes = classes.replace("text-white", "text-black");
classes = classes.replace("bg-blue-500", "bg-transparent");
cur.className = classes;

// add highlight
const next = document.querySelector(`#spotlight-${this.curSelection}`);
classes = next.className;
classes = classes.replace("text-black", "text-white");
classes = classes.replace("bg-transparent", "bg-blue-500");
next.className = classes;

// get details of the current selected app
this.getCurDetails();
};

keyPress = (e) => {
const keyCode = e.key;
const $curApp = document.querySelector(`#spotlight-${this.curSelection}`);

// ----------- select next app -----------
if (keyCode === "ArrowDown" && this.curSelection < this.appIndices - 1) {
this.curSelection++;
this.handleHighlight($curApp);
}
// ----------- select previous app -----------
else if (keyCode === "ArrowUp" && this.curSelection > 0) {
this.curSelection--;
this.handleHighlight($curApp);
}
// ----------- launch app -----------
else if (keyCode === "Enter") {
if (!this.state.curDetails) return;
if (this.state.curDetails.type === "app" && !this.state.curDetails.link) {
this.props.openApp(this.state.curDetails.id);
this.props.toggleSpotlight();
} else {
window.open(this.state.curDetails.link);
this.props.toggleSpotlight();
}
}
};

handleInputChange = (e) => {
// current selected id go back to 0
this.curSelection = 0;
// update search text and guess app list
this.appIndices = 0;
this.setState(
{
searchText: e.target.value
},
() => this.updateAppList()
);
// don't show app details when there is no input
if (e.target.value === "") this.setState({ curDetails: null });
};

focusOnInput = () => {
document.querySelector("#spotlight-input").focus();
};

render() {
return (
<div
className="spotlight fixed mt-32 h-max rounded-md bg-gray-50 bg-opacity-80 blur border border-gray-400 border-opacity-50 shadow-2xl"
style={{ zIndex: 99997 }}
onKeyDown={this.keyPress}
onClick={this.focusOnInput}
>
<div className="w-full grid grid-cols-8 sm:grid-cols-11 h-14 rounded-md bg-transparent">
<div className="col-start-1 col-span-1 flex justify-center items-center">
<BiSearch className="ml-1 text-gray-600" size={28} />
</div>
<input
id="spotlight-input"
className="col-start-2 col-span-7 sm:col-span-10 outline-none focus:outline-none bg-transparent px-1 text-black text-2xl"
placeholder="Spotlight Search"
value={this.state.searchText}
onChange={(e) => this.handleInputChange(e)}
autoFocus={true}
/>
</div>
{this.state.searchText !== "" && (
<div
className="bg-transparent flex flex-row border-t border-gray-400 border-opacity-50"
style={{ height: "340px" }}
>
<div className="flex-none w-32 sm:w-72 border-r border-gray-400 border-opacity-50">
{this.state.appList}
</div>
<div className="flex-grow">
{this.state.curDetails && (
<div className="h-full w-full flex flex-col">
<div className="mx-auto w-4/5 flex-none flex flex-col items-center justify-center h-56 border-b border-gray-400 border-opacity-50">
<img
className="w-32 mx-auto"
src={this.state.curDetails.img}
alt={this.state.curDetails.title}
title={this.state.curDetails.title}
/>
<div className="mt-4 text-xl text-black">
{this.state.curDetails.title}
</div>
<div className="text-xs text-gray-500">
{`Version: ${getRandom(0, 99)}.${getRandom(0, 999)}`}
</div>
</div>
<div className="flex-grow flex flex-row text-xs">
<div className="flex-none w-1/2 flex flex-col items-end justify-center text-gray-500">
<div>Kind</div>
<div>Size</div>
<div>Created</div>
<div>Modified</div>
<div>Last opened</div>
</div>
<div className="pl-2 flex-grow flex flex-col items-start justify-center text-black">
<div>
{this.state.curDetails.type === "app"
? "Application"
: "Portfolio"}
</div>
<div>{`${getRandom(0, 999)} G`}</div>
<div>{getRandomDate()}</div>
<div>{getRandomDate()}</div>
<div>{getRandomDate()}</div>
</div>
</div>
</div>
)}
</div>
</div>
)}
</div>
);
}
}
2 changes: 1 addition & 1 deletion src/components/Window.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export default class Window extends Component {
maxW: maxW,
maxH: maxH,
x: Math.random() * (maxW - width),
y: Math.random() * (maxH - height - 100)
y: Math.random() * (maxH - height)
};
this.resize.bind(this);
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/apps/Terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class HowDare extends Component {
intervalId: null
};
this.font_size = 12;
this.emoji = getEmoji();
}

componentDidMount() {
Expand Down Expand Up @@ -85,7 +86,7 @@ class HowDare extends Component {
>
<canvas id="how-dare"></canvas>
<div className="font-jost absolute text-center h-28 mx-auto -mt-20 bottom-0 left-0 right-0 top-1/2">
<div class="text-4xl">{getEmoji()}</div>
<div className="text-4xl">{this.emoji}</div>
<div className="text-3xl mt-4">HOW DARE YOU!</div>
<div className="mt-4">Click to go back</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/menus/TopBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class TopBar extends Component {
<TopBarItem hideOnMobile={true}>
<FaWifi size={17} />
</TopBarItem>
<TopBarItem hideOnMobile={true}>
<TopBarItem onClick={this.props.toggleSpotlight}>
<BiSearch size={17} />
</TopBarItem>
<TopBarItem
Expand Down
4 changes: 2 additions & 2 deletions src/configs/apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const apps = [
id: "bear",
title: "Bear",
desktop: true,
show: false,
show: true,
width: 860,
height: 500,
img: "img/icons/bear.png",
Expand Down Expand Up @@ -53,7 +53,7 @@ const apps = [
id: "terminal",
title: "Terminal",
desktop: true,
show: true,
show: false,
img: "img/icons/terminal.png",
content: <Terminal />
},
Expand Down
2 changes: 1 addition & 1 deletion src/configs/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const terminal = [
title: "who-cares.txt",
type: "file",
content:
"I'm open to summer research / algorithm engineer internships for 2021 (base in China) lol."
"I'm open to research / algorithm engineer internships for summer 2021 (base in China) lol."
},
{
id: "about-contact",
Expand Down
17 changes: 16 additions & 1 deletion src/pages/Desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import TopBar from "../components/menus/TopBar";
import Dock from "../components/dock/Dock";
import Launchpad from "../components/Launchpad";
import Window from "../components/Window";
import Spotlight from "../components/Spotlight";
import apps from "../configs/apps";
import wallpapers from "../configs/wallpapers";

Expand All @@ -20,7 +21,8 @@ class Desktop extends Component {
maxZ: 2,
showLaunchpad: false,
currentTitle: "Finder",
hideDock: false
hideDock: false,
spotlight: false
};
}

Expand Down Expand Up @@ -69,6 +71,10 @@ class Desktop extends Component {
this.setState({ showLaunchpad: target });
};

toggleSpotlight = () => {
this.setState({ spotlight: !this.state.spotlight });
};

setWinowsPosition = (id) => {
let r = document.querySelector(`#window-${id}`);
const rect = r.getBoundingClientRect();
Expand Down Expand Up @@ -217,11 +223,20 @@ class Desktop extends Component {
shutMac={this.props.shutMac}
sleepMac={this.props.sleepMac}
restartMac={this.props.restartMac}
toggleSpotlight={this.toggleSpotlight}
/>

{/* Desktop Apps */}
{this.renderAppWindows()}

{/* Spotlight */}
{this.state.spotlight && (
<Spotlight
openApp={this.openApp}
toggleSpotlight={this.toggleSpotlight}
/>
)}

{/* Launchpad */}
<Launchpad show={this.state.showLaunchpad} />

Expand Down
Loading

0 comments on commit a3c6a44

Please sign in to comment.