diff --git a/.gitignore b/.gitignore
index 8335cec..76e620e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ prisma/migrations/*
output.xml
report.html
log.html
-.expo
\ No newline at end of file
+.expo
+node_modules/
\ No newline at end of file
diff --git a/front/Navigation.tsx b/front/Navigation.tsx
index 276cb43..3292f76 100644
--- a/front/Navigation.tsx
+++ b/front/Navigation.tsx
@@ -2,6 +2,7 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
import React from 'react';
import AuthenticationView from './views/AuthenticationView';
import HomeView from './views/HomeView';
+import SearchView from './views/SearchView';
import SetttingsNavigator from './views/SettingsView';
import { NavigationContainer } from '@react-navigation/native';
import { useSelector } from './state/Store';
@@ -14,6 +15,7 @@ export const protectedRoutes = <>
+
>;
export const publicRoutes =
diff --git a/front/components/SearchBar.tsx b/front/components/SearchBar.tsx
new file mode 100644
index 0000000..2429814
--- /dev/null
+++ b/front/components/SearchBar.tsx
@@ -0,0 +1,150 @@
+import {
+ Input,
+ Column,
+ Row,
+ Text,
+ Pressable,
+ HStack,
+ VStack,
+ Image,
+ Icon,
+ Square,
+} from "native-base";
+import React from "react";
+import { Ionicons, FontAwesome } from "@expo/vector-icons";
+
+export enum SuggestionType {
+ TEXT,
+ ILLUSTRATED,
+}
+
+export type SuggestionList = {
+ type: SuggestionType;
+ data: SuggestionProps | IllustratedSuggestionProps;
+}[];
+
+export interface SearchBarProps {
+ onTextChange: (text: string) => void;
+ onTextSubmit: (text: string) => void;
+ suggestions: SuggestionList;
+}
+export interface IllustratedSuggestionProps {
+ text: string;
+ subtext: string;
+ imageSrc: string;
+ onPress: () => void;
+}
+
+export interface SuggestionProps {
+ text: string;
+ onPress: () => void;
+}
+
+// debounce function
+const debounce = (func: any, delay: number) => {
+ let inDebounce: any;
+ return function (this: any) {
+ const context = this;
+ const args = arguments;
+ clearTimeout(inDebounce);
+ inDebounce = setTimeout(() => func.apply(context, args), delay);
+ };
+};
+
+const IllustratedSuggestion = ({
+ text,
+ subtext,
+ imageSrc,
+ onPress,
+}: IllustratedSuggestionProps) => {
+ return (
+
+
+
+
+
+
+ {text}
+
+ {subtext}
+
+
+
+
+ );
+};
+
+const TextSuggestion = ({ text, onPress }: SuggestionProps) => {
+ return (
+
+
+
+
+
+ {text}
+
+
+ );
+};
+
+// render the suggestions based on the type
+const SuggestionRenderer = (suggestions: SuggestionList) => {
+ const suggestionRenderers = {
+ [SuggestionType.TEXT]: TextSuggestion,
+ [SuggestionType.ILLUSTRATED]: IllustratedSuggestion,
+ };
+ return suggestions.map((suggestion, index) => {
+ const SuggestionComponent = suggestionRenderers[suggestion.type];
+ return ;
+ });
+};
+
+const SearchBar = ({
+ onTextChange,
+ onTextSubmit,
+ suggestions,
+}: SearchBarProps) => {
+ const debouncedOnTextChange = React.useRef(
+ debounce((t: string) => onTextChange(t), 70)
+ ).current;
+ return (
+ <>
+ onTextSubmit(event.nativeEvent.text)}
+ />
+ {SuggestionRenderer(suggestions)}
+ >
+ );
+};
+
+export default SearchBar;
\ No newline at end of file
diff --git a/front/components/SearchBarSuggestions.tsx b/front/components/SearchBarSuggestions.tsx
new file mode 100644
index 0000000..3772a95
--- /dev/null
+++ b/front/components/SearchBarSuggestions.tsx
@@ -0,0 +1,41 @@
+import React from "react";
+import SearchBar from "../components/SearchBar";
+import { SuggestionList, SuggestionType } from "../components/SearchBar";
+interface SearchBarSuggestionsProps {
+ onTextSubmit: (text: string) => void;
+ suggestions: SuggestionList;
+}
+
+// do a function that takes in a string and returns a list of filtered suggestions
+const filterSuggestions = (text: string, suggestions: SuggestionList) => {
+ return suggestions.filter((suggestion) => {
+ switch (suggestion.type) {
+ case SuggestionType.TEXT:
+ return suggestion.data.text.toLowerCase().includes(text.toLowerCase());
+ case SuggestionType.ILLUSTRATED:
+ return (
+ suggestion.data.text.toLowerCase().includes(text.toLowerCase()) ||
+ suggestion.data.subtext.toLowerCase().includes(text.toLowerCase())
+ );
+ }
+ });
+};
+
+const SearchBarSuggestions = ({
+ onTextSubmit,
+ suggestions,
+}: SearchBarSuggestionsProps) => {
+ const [searchText, setSearchText] = React.useState("");
+
+ return (
+ setSearchText(t)}
+ onTextSubmit={onTextSubmit}
+ suggestions={
+ searchText === "" ? [] : filterSuggestions(searchText, suggestions)
+ }
+ />
+ );
+};
+
+export default SearchBarSuggestions;
diff --git a/front/components/SongCard.tsx b/front/components/SongCard.tsx
index 98bc10a..3216fa0 100644
--- a/front/components/SongCard.tsx
+++ b/front/components/SongCard.tsx
@@ -18,7 +18,7 @@ const SongCard = (props: SongCardProps) => {
shadow={3}
flexDirection='column'
alignContent='space-around'
- bg={(isHovered || isFocused) ? 'coolGray.200' : undefined }
+ bg={(isHovered || isFocused) ? 'coolGray.200' : 'background.50' }
>
{
+ console.log(text);
+};
+
+const SearchView = () => {
+ const navigation = useNavigation();
+
+ const IllustratedSuggestion: IllustratedSuggestionProps = {
+ text: "Love Story",
+ subtext: "Taylor Swift",
+ imageSrc:
+ "https://i.discogs.com/yHqu3pnLgJq-cVpYNVYu6mE-fbzIrmIRxc6vES5Oi48/rs:fit/g:sm/q:90/h:556/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTE2NjQ2/ODUwLTE2MDkwNDU5/NzQtNTkxOS5qcGVn.jpeg",
+ onPress: () => navigation.navigate("Song", { songId: 1 }),
+ };
+ // fill the suggestions with the data from the backend
+ const suggestions: SuggestionList = [
+ {
+ type: SuggestionType.ILLUSTRATED,
+ data: IllustratedSuggestion,
+ },
+ {
+ type: SuggestionType.ILLUSTRATED,
+ data: IllustratedSuggestion,
+ },
+ {
+ type: SuggestionType.ILLUSTRATED,
+ data: {
+ text: "Shed a Light",
+ subtext: "Robin Schulz & David Guetta",
+ imageSrc:
+ "https://imgs.search.brave.com/O9j2Z-oWiniq3lj7d-dAOgXLWCIqnHaFegmaSeIkWOY/rs:fit:560:320:1/g:ce/aHR0cHM6Ly91cGxv/YWQud2lraW1lZGlh/Lm9yZy93aWtpcGVk/aWEvZW4vdGh1bWIv/OC84ZS9TaGVkX2Ff/TGlnaHRfUm9iaW5f/U2NodWx6LmpwZy81/MTJweC1TaGVkX2Ff/TGlnaHRfUm9iaW5f/U2NodWx6LmpwZw",
+ onPress: () => navigation.navigate("Song", { songId: 1 }),
+ },
+ },
+ {
+ type: SuggestionType.TEXT,
+ data: {
+ text: "Lady Gaga",
+ onPress: () => navigation.navigate("Song", { songId: 1 }),
+ },
+ },
+ ];
+
+ return (
+
+
+
+ );
+};
+
+export default SearchView;
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 64e05ed..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "Chromacase",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {}
-}
diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index fb57ccd..0000000
--- a/yarn.lock
+++ /dev/null
@@ -1,4 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-