- {catalogs.map(({ req, content }, index) => {
+ {catalogs.map(({ request, content }, index) => {
switch (content.type) {
case 'Ready':
return (
);
case 'Message':
return (
);
case 'Loading':
return (
);
}
diff --git a/src/routes/Board/useCatalogs.js b/src/routes/Board/useCatalogs.js
index d2470ff9e..ce865f2d5 100644
--- a/src/routes/Board/useCatalogs.js
+++ b/src/routes/Board/useCatalogs.js
@@ -7,13 +7,13 @@ const useCatalogs = () => {
React.useEffect(() => {
const onNewState = () => {
const state = core.getState();
- setCatalogs(state.board.groups);
+ setCatalogs(state.board.items_groups);
};
core.on('NewModel', onNewState);
core.dispatch({
action: 'Load',
args: {
- load: 'CatalogGrouped',
+ load: 'CatalogsGrouped',
args: { extra: [] }
}
});
diff --git a/src/routes/Search/Search.js b/src/routes/Search/Search.js
index b97096a5b..b91fbea06 100644
--- a/src/routes/Search/Search.js
+++ b/src/routes/Search/Search.js
@@ -1,21 +1,77 @@
const React = require('react');
+const Icon = require('stremio-icons/dom');
const { MainNavBar, MetaRow } = require('stremio/common');
const useSearch = require('./useSearch');
const styles = require('./styles');
const Search = ({ queryParams }) => {
- const groups = useSearch(queryParams.get('q'));
+ const search = useSearch(queryParams);
+ const searchSelected = React.useMemo(() => {
+ return search.selected.some(([name, value]) => name === 'search' && value.length > 0)
+ }, [search.selected]);
return (
- {groups.map((group, index) => (
-
- ))}
+ {
+ searchSelected ?
+ search.items_groups && search.items_groups.length > 0 ?
+ search.items_groups.some(group => group.content.type !== 'Err') ?
+ search.items_groups.map(({ href, request, content }, index) => {
+ switch (content.type) {
+ case 'Ready':
+ return (
+
+ );
+ case 'Err':
+ return (
+
+ );
+ case 'Loading':
+ return (
+
+ );
+ }
+ })
+ :
+
+
+
No metadata was found
+
+
+ :
+
+
+
No addons were requested for metadata
+
+
+ :
+
+
+
+
Search for movies, series, YouTube and TV channels
+
+
+
+
Search for actors, directors and writers
+
+
+ }
);
diff --git a/src/routes/Search/styles.less b/src/routes/Search/styles.less
index 40e01a4d2..c5f3308a9 100644
--- a/src/routes/Search/styles.less
+++ b/src/routes/Search/styles.less
@@ -1,7 +1,13 @@
+@import (reference) '~stremio/common/screen-sizes.less';
+
:import('~stremio/common/MetaRow/styles.less') {
meta-item: meta-item;
}
+:import('~stremio/common/MetaRow/MetaRowPlaceholder/styles.less') {
+ meta-item-placeholder: meta-item;
+}
+
.search-container {
display: flex;
flex-direction: column;
@@ -19,7 +25,7 @@
align-self: stretch;
overflow-y: auto;
- .search-row {
+ .search-row, .search-row-placeholder {
margin: 4rem 2rem;
&:first-child {
@@ -29,10 +35,111 @@
&:last-child {
margin-bottom: 2rem;
}
+ }
- .meta-item {
- &:nth-child(n+6) {
- display: none;
+ .message-container {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ justify-content: center;
+ margin: 5rem;
+
+ .message-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+
+ .icon {
+ flex: none;
+ width: 6rem;
+ height: 6rem;
+ margin-bottom: 2rem;
+ fill: var(--color-surfacelighter40);
+ }
+
+ .label {
+ flex-grow: 0;
+ flex-shrink: 1;
+ flex-basis: auto;
+ font-size: 1.2rem;
+ color: var(--color-surfacelighter40);
+ text-align: center;
+ }
+
+ &:not(:last-child) {
+ margin-right: 5rem;;
+ }
+ }
+ }
+ }
+}
+
+@media only screen and (min-width: @large) {
+ .board-container {
+ .board-content {
+ .board-row, .board-row-placeholder {
+ .meta-item, .meta-item-placeholder {
+ &:nth-child(n+9) {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media only screen and (max-width: @large) {
+ .search-container {
+ .search-content {
+ .search-row, .search-row-placeholder {
+ .meta-item, .meta-item-placeholder {
+ &:nth-child(n+8) {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media only screen and (max-width: @medium) {
+ .search-container {
+ .search-content {
+ .search-row, .search-row-placeholder {
+ .meta-item, .meta-item-placeholder {
+ &:nth-child(n+7) {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media only screen and (max-width: @small) {
+ .search-container {
+ .search-content {
+ .search-row, .search-row-placeholder {
+ .meta-item, .meta-item-placeholder {
+ &:nth-child(n+6) {
+ display: none;
+ }
+ }
+ }
+ }
+ }
+}
+
+@media only screen and (max-width: @xsmall) {
+ .search-container {
+ .search-content {
+ .search-row, .search-row-placeholder {
+ .meta-item, .meta-item-placeholder {
+ &:nth-child(n+5) {
+ display: none;
+ }
}
}
}
diff --git a/src/routes/Search/useSearch.js b/src/routes/Search/useSearch.js
index 68289c202..331a34143 100644
--- a/src/routes/Search/useSearch.js
+++ b/src/routes/Search/useSearch.js
@@ -1,32 +1,53 @@
const React = require('react');
+const { useServices } = require('stremio/services');
-const useSearch = (query) => {
- const items = React.useMemo(() => {
- return [
- {
- title: 'demo addon',
- items: [
- {
- id: '1',
- type: 'movie',
- name: 'Stremio demo item movie 1',
- poster: '/images/intro_background.jpg',
- logo: '/images/default_avatar.png',
- posterShape: 'poster'
- },
- {
- id: '2',
- type: 'movie',
- name: 'Stremio demo item movie 2',
- poster: '/images/intro_background.jpg',
- logo: '/images/default_avatar.png',
- posterShape: 'poster'
- },
- ]
- }
- ];
- }, [query]);
- return items;
+const mapSearchState = (state) => {
+ const query = state.search.selected.reduceRight((query, [name, value]) => {
+ if (name === 'search') {
+ return value;
+ }
+ return query;
+ }, '');
+ const selected = state.search.selected;
+ const items_groups = state.search.items_groups.map((group) => {
+ group.href = `#/discover/${encodeURIComponent(group.request.base)}/${encodeURIComponent(group.request.path.id)}/${encodeURIComponent(group.request.path.type_name)}?search=${query}`;
+ return group;
+ });
+ return { selected, items_groups };
+};
+
+const useSearch = (queryParams) => {
+ const { core } = useServices();
+ const [search, setSearch] = React.useState(() => {
+ const state = core.getState();
+ const search = mapSearchState(state);
+ return search;
+ });
+ React.useEffect(() => {
+ const onNewState = () => {
+ const state = core.getState();
+ const search = mapSearchState(state);
+ setSearch(search);
+ };
+ core.on('NewModel', onNewState);
+ if (queryParams.has('search')) {
+ core.dispatch({
+ action: 'Load',
+ args: {
+ load: 'CatalogsGrouped',
+ args: {
+ extra: [
+ ['search', queryParams.get('search')]
+ ]
+ }
+ }
+ });
+ }
+ return () => {
+ core.off('NewModel', onNewState);
+ };
+ }, [queryParams]);
+ return search;
};
module.exports = useSearch;