mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-14 16:37:27 +00:00
Merge pull request #401 from JohnRawlins/feature/add-page-title-to-address-bar
Feature/add page title to address bar
This commit is contained in:
commit
a9e396aba2
6 changed files with 137 additions and 63 deletions
|
@ -174,10 +174,6 @@ class AddressBar extends React.Component<Props> {
|
|||
</div>
|
||||
{this.state.finalUrlResult?.length && this.state.canShowSuggestions ? (
|
||||
<UrlSearchResults
|
||||
divClassName={cx(styles.searchBarSuggestionsContainer)}
|
||||
listItemUiClassName={cx(styles.searchBarSuggestionsListUl)}
|
||||
listItemsClassName={cx(styles.searchBarSuggestionsListItems)}
|
||||
activeClass={cx(styles.searchBarSuggestionsActiveListItems)}
|
||||
filteredSearchResults={this.state.finalUrlResult}
|
||||
cursorIndex={this.state.cursor}
|
||||
handleUrlChange={this._onSearchedUrlClick}
|
||||
|
|
|
@ -39,41 +39,3 @@
|
|||
display: flex;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsContainer {
|
||||
width: calc(100% + 2px);
|
||||
max-height: 20em;
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
top: 1.8em;
|
||||
background: #4b4b4c;
|
||||
border-radius: 0 0 14px 14px;
|
||||
border-right: solid 1px #7587ec;
|
||||
border-bottom: solid 1px #7587ec;
|
||||
border-left: solid 1px #7587ec;
|
||||
}
|
||||
.searchBarSuggestionsListItems {
|
||||
line-height: 22px;
|
||||
color: #cacaca;
|
||||
padding: 0.4em 1em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsListUl {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsListItems:hover {
|
||||
background: gray;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsActiveListItems {
|
||||
background: #7587ec;
|
||||
color: white;
|
||||
}
|
||||
|
|
|
@ -1,31 +1,60 @@
|
|||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import styles from './style.css';
|
||||
import DefaultFavIcon from '@material-ui/icons/Public';
|
||||
|
||||
const UrlSearchResults = ({
|
||||
divClassName,
|
||||
listItemsClassName,
|
||||
filteredSearchResults,
|
||||
cursorIndex,
|
||||
handleUrlChange,
|
||||
activeClass,
|
||||
listItemUiClassName,
|
||||
}) => (
|
||||
<div className={divClassName}>
|
||||
<ul className={listItemUiClassName}>
|
||||
{filteredSearchResults?.map(
|
||||
(eachResult, index) =>
|
||||
<div className={cx(styles.searchBarSuggestionsContainer)}>
|
||||
<ul className={cx(styles.searchBarSuggestionsListUl)}>
|
||||
{filteredSearchResults?.map((eachResult, index) => {
|
||||
const favicon = eachResult.pageMeta?.favicons?.[0];
|
||||
const title = eachResult.pageMeta?.title;
|
||||
const url = eachResult.url;
|
||||
return (
|
||||
index < 8 && (
|
||||
<li
|
||||
key={index}
|
||||
className={`${listItemsClassName} ${
|
||||
cursorIndex === index ? activeClass : ''
|
||||
}`}
|
||||
>
|
||||
<div onClick={() => handleUrlChange(eachResult.url, index)}>
|
||||
{eachResult.url}
|
||||
<li key={url}>
|
||||
<div
|
||||
className={cx(styles.searchBarSuggestionsListItems, {
|
||||
[styles.searchBarSuggestionsActiveListItems]:
|
||||
cursorIndex === index,
|
||||
})}
|
||||
onClick={() => handleUrlChange(eachResult.url, index)}
|
||||
>
|
||||
<div className={cx(styles.pageFavIconWrapper)}>
|
||||
{favicon ? (
|
||||
<img
|
||||
className={cx(styles.pageFavIcon)}
|
||||
src={favicon}
|
||||
onError={event => {
|
||||
event.target.style.display = 'none';
|
||||
event.target.nextSibling.style.display = 'block';
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className={cx(styles.pageDefaultFavIconWrapper)}>
|
||||
<DefaultFavIcon fontSize="inherit" />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
style={{display: 'none'}}
|
||||
className={cx(styles.pageDefaultFavIconWrapperClassName)}
|
||||
>
|
||||
<DefaultFavIcon fontSize="inherit" />
|
||||
</div>
|
||||
</div>
|
||||
<div className={cx(styles.pageTitleAndUrlContainer)}>
|
||||
<span className={cx(styles.pageTitle)}>{title}</span>
|
||||
<span className={cx(styles.pageUrl)}>{url}</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
70
desktop-app/app/components/UrlSearchResults/style.css
Normal file
70
desktop-app/app/components/UrlSearchResults/style.css
Normal file
|
@ -0,0 +1,70 @@
|
|||
.searchBarSuggestionsContainer {
|
||||
width: calc(100% + 2px);
|
||||
max-height: 20em;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
left: -1px;
|
||||
top: 1.8em;
|
||||
background: #4b4b4c;
|
||||
border-radius: 0 0 14px 14px;
|
||||
border-right: solid 1px #7587ec;
|
||||
border-bottom: solid 1px #7587ec;
|
||||
border-left: solid 1px #7587ec;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsListUl {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsListItems {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 22px;
|
||||
color: #cacaca;
|
||||
padding: 0.4em 1em;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsActiveListItems {
|
||||
background: #7587ec;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.searchBarSuggestionsListItems:hover {
|
||||
background: gray;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pageFavIconWrapper {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.pageFavIcon {
|
||||
display: block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.pageDefaultFavIconWrapper {
|
||||
font-size: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.pageTitleAndUrlContainer {
|
||||
margin-left: 16px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.pageTitle::after {
|
||||
content: '-';
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.pageUrl {
|
||||
font-weight: bold;
|
||||
}
|
|
@ -361,6 +361,10 @@ export default function browser(
|
|||
updateExistingUrl(action.address);
|
||||
return {...state, address: action.address, currentPageMeta: {}};
|
||||
case NEW_PAGE_META_FIELD:
|
||||
updateExistingUrl(state.address, {
|
||||
name: action.name,
|
||||
value: action.value,
|
||||
});
|
||||
return {
|
||||
...state,
|
||||
currentPageMeta: {
|
||||
|
|
|
@ -28,9 +28,15 @@ const _sortedExistingUrlSearchResult = filteredData => {
|
|||
|
||||
export const searchUrlUtils = url => {
|
||||
if (url) {
|
||||
const filteredData = filter(previousSearchResults, eachResult =>
|
||||
eachResult.url.toLowerCase().includes(url)
|
||||
);
|
||||
const filteredData = filter(previousSearchResults, eachResult => {
|
||||
if (eachResult.pageMeta?.title) {
|
||||
return (
|
||||
eachResult.pageMeta.title.toLowerCase().includes(url) ||
|
||||
eachResult.url.toLowerCase().includes(url)
|
||||
);
|
||||
}
|
||||
return eachResult.url.toLowerCase().includes(url);
|
||||
});
|
||||
const finalResult = _sortedExistingUrlSearchResult(filteredData);
|
||||
return finalResult;
|
||||
}
|
||||
|
@ -48,7 +54,7 @@ const normalizeURL = url => {
|
|||
return url;
|
||||
};
|
||||
|
||||
export const updateExistingUrl = url => {
|
||||
export const updateExistingUrl = (url, pageMeta = null) => {
|
||||
url = normalizeURL(url);
|
||||
if (previousSearchResults?.length) {
|
||||
let updatedSearchResults = [...previousSearchResults];
|
||||
|
@ -60,6 +66,12 @@ export const updateExistingUrl = url => {
|
|||
if (index !== (undefined || -1 || null)) {
|
||||
updatedSearchResults[index].visitedCount =
|
||||
1 + updatedSearchResults[index].visitedCount;
|
||||
if (pageMeta) {
|
||||
updatedSearchResults[index].pageMeta = {
|
||||
...updatedSearchResults[index].pageMeta,
|
||||
[pageMeta.name]: pageMeta.value,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
updatedSearchResults = [
|
||||
{url, visitedCount: 1},
|
||||
|
@ -75,6 +87,7 @@ export const updateExistingUrl = url => {
|
|||
url,
|
||||
visitedCount: 1,
|
||||
});
|
||||
|
||||
addUrlToSearchResults(addNewUrl);
|
||||
previousSearchResults = addNewUrl;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue