Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
mica committed Feb 26, 2024
0 parents commit 28ce635
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 0 deletions.
1 change: 1 addition & 0 deletions CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
multisearch.app
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## MultiSearch / [multisearch.app](https://multisearch.app)

In a world where people insist on using 5 different classifieds sites, multisearch.app allows them all to be searched from one place.

Leave a message in the Issues tab above, and I'll add your city — or any other category of site you think could use a MultiSearch.
34 changes: 34 additions & 0 deletions dc/index.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<html>
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RG226NDPQM"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-RG226NDPQM');
</script>
<meta charset='utf-8'>
<title>DC Classifieds MultiSearch</title>
<link href='../style.css' rel='stylesheet'>
</head>
<body>
<header></header>
<main>
<h1>MultiSearch</h1>
<h2>Washington, DC Classifieds</h2>
<form method='get'>
<input id='search' name='q' value=''>
<input type='submit' value='Search'>
<div></div>
</form>
</main>
<footer></footer>
<script>
const sites = [
['FB Marketplace','https://www.facebook.com/marketplace/dc/search/?query='],
['Craigslist','https://washingtondc.craigslist.org/search/sss?purveyor=owner&query=']
];
</script>
<script type='module' src='../script.js'></script>
</body>
</html>
35 changes: 35 additions & 0 deletions edm/index.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<html>
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RG226NDPQM"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-RG226NDPQM');
</script>
<meta charset='utf-8'>
<title>Edmonton Classifieds MultiSearch</title>
<link href='../style.css' rel='stylesheet'>
</head>
<body>
<header></header>
<main>
<h1>MultiSearch</h1>
<h2>Edmonton, AB Classifieds</h2>
<form method='get'>
<input id='search' name='q' value=''>
<input type='submit' value='Search'>
<div></div>
</form>
</main>
<footer></footer>
<script>
const sites = [
['FB Marketplace','https://www.facebook.com/marketplace/edmonton/search/?query='],
['Craigslist','https://edmonton.craigslist.org/search/sss?purveyor=owner&query='],
['Kijiji','https://www.kijiji.ca/b-edmonton/', '/k0l1700203']
];
</script>
<script type='module' src='../script.js'></script>
</body>
</html>
25 changes: 25 additions & 0 deletions index.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<html>
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RG226NDPQM"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-RG226NDPQM');
</script>
<meta charset='utf-8'>
<title>MultiSearch</title>
<link href='./style.css' rel='stylesheet'>
</head>
<body>
<main>
<h1>MultiSearch</h1>
<h2>Classifieds:</h2>
<a href='./vic'>Victoria, BC</a><br><br>
<a href='./van'>Vancouver, BC</a><br><br>
<a href='./edm'>Edmonton, AB</a><br><br>
<a href='./dc'>Washington, DC</a>
</main>
<footer onclick='window.open("https://github.com/mica/multisearch.app")'></footer>
</body>
</html>
78 changes: 78 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const urlParams = new URLSearchParams(location.search);
let q = urlParams.get('q');
document.querySelector('header').innerText = 'Allow popups for Open All button to work';
document.querySelector('form div').innerText = 'for multiple searches, separate with commas';
document.querySelector('footer').addEventListener('click', () => window.open('https://github.com/mica/multisearch.app'));
if (q) {
document.getElementById('search').value = q;
q = q.split(',').filter(e => {return e !== ''}).map(e => e.trim());
if (q.length > 1) {
const span = document.createElement('span');
span.classList.add('hidden');
span.innerText = 'Multi';
document.querySelector('h1').prepend(span);
setTimeout(() => {
span.classList.add('fade');
span.classList.remove('hidden');
}, 300);
}
q.reverse().forEach((search, i) => {
if (!search.length == i) {
document.title = search + ' - ' + document.title;
} else {
document.title = search + ', ' + document.title;
}
});
q.reverse().forEach((search, i) => {
setTimeout(() => {
mkBtns(search, i);
}, 40 * (i + 1));
});
}
function mkBtns(search, i) {
const btns = document.createElement('div');
btns.classList.add('btns');
document.querySelector('main').insertAdjacentElement('beforeend', btns)
sites.forEach(site => {
const btnIcon = document.createElement('img');
btnIcon.src = 'https://www.google.com/s2/favicons?domain=' + site[1].split('/')[2];
const btnSite = document.createElement('div');
btnSite.classList.add('btnSite');
btnSite.append(btnIcon, site[0]);
const btnTxt = document.createElement('div');
btnTxt.classList.add('btnTxt');
btnTxt.innerHTML = `<small>search</small><br>“<span>${search}</span>”`;
const btn = document.createElement('div');
btn.classList.add('btn');
btn.append(btnSite, btnTxt);
const btnLink = document.createElement('a');
btnLink.href = site[1] + encodeURIComponent(search);
if (site[2]) {
btnLink.href = btnLink.href + site[2];
}
btnLink.classList.add('hidden');
btnLink.append(btn);
document.getElementsByClassName('btns')[i].append(btnLink);
});
const allTxt = document.createElement('div');
allTxt.innerHTML = '<span>Open All</span><br>in new tabs';
const allBtn = document.createElement('div');
allBtn.classList.add('btnAll');
allBtn.classList.add('hidden');
allBtn.append(allTxt);
allBtn.addEventListener('click', openAll);
document.getElementsByClassName('btns')[i].append(allBtn);
document.getElementsByClassName('btns')[i].childNodes.forEach((btn, i) => {
setTimeout(() => {
btn.classList.add('fade');
btn.classList.remove('hidden');
}, 40 * (i + 1));
})
}
function openAll() {
let links = this.parentElement.getElementsByTagName('a');
links = [...links];
links.reverse().forEach(link => {
window.open(link.href);
});
}
152 changes: 152 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400&display=swap');
body {
background-color: #fcfcfc;
text-align: center;
font-family: 'Montserrat', sans-serif;
}
a, a:visited {
text-decoration: none;
color: #000;
}
/* light grey backgrounds */
.btn, #search {
background-color: #f9f9f9;
}
/* dark grey backgrounds */
.btnSite, .btnAll, input[type='submit'] {
background-color: #eee;
}
main {
padding-top: 120px;
}
header {
padding-left: 25px;
position: absolute;
top: 15px;
right: 100px;
font-size: 83%;
color: #888;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="grey" class="bi bi-arrow-up-circle" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-7.5 3.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11.5z"/></svg>');
background-repeat: no-repeat;
}
footer {
position: absolute;
bottom: 20px;
right: 20px;
width: 30px;
height: 30px;
cursor: pointer;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="grey" class="bi bi-question-circle" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/></svg>');
background-repeat: no-repeat;
background-size: cover;
}
h1 {
margin: 0;
font-weight: 300;
}
h1 span {
margin-right: 2px;
font-size: 55%;
}
h2 {
margin: 10px 0 18px 0;
font-weight: 300;
}
input {
margin: 2px;
padding: 10px;
border: 1px solid #bbb;
border-radius: 5px;
font-size: 120%;
font-family: inherit;
}
input:focus-visible {
outline: none;
}
input[type='submit'] {
font-size: 105%;
}
form {
margin: 0;
}
form div {
margin: 10px 0 14px 0;
font-size: 83%;
color: #aaa;
}
.btns {
margin-bottom: 8px;
display: flex;
flex-flow: wrap;
justify-content: center;
}
.btn, .btnAll {
margin: 4px;
position: relative;
width: 145px;
height: 95px;
float: left;
border: 1px solid #bbb;
border-radius: 5px;
cursor: pointer;
}
.btnSite {
padding: 4px 0 2px 0;
border-bottom: 1px solid #ddd;
border-radius: 5px 5px 0 0;
font-size: 85%;
white-space: nowrap;
overflow: hidden;
}
.btnSite img {
margin: 0px 5px 3px 3px;
vertical-align: middle;
}
.btnTxt, .btnAll div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.btnTxt {
margin: 6px 2px 0 2px;
color: #bbb;
font-size: 105%;
}
.btnTxt span {
color: #000;
}
.btnTxt small {
font-size: 80%;
}
.btnAll {
color: #bbb;
font-size: 80%;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="grey" class="bi bi-box-arrow-in-up-right" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M6.364 13.5a.5.5 0 0 0 .5.5H13.5a1.5 1.5 0 0 0 1.5-1.5v-10A1.5 1.5 0 0 0 13.5 1h-10A1.5 1.5 0 0 0 2 2.5v6.636a.5.5 0 1 0 1 0V2.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 .5.5v10a.5.5 0 0 1-.5.5H6.864a.5.5 0 0 0-.5.5z"/><path fill-rule="evenodd" d="M11 5.5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793l-8.147 8.146a.5.5 0 0 0 .708.708L10 6.707V10.5a.5.5 0 0 0 1 0v-5z"/></svg>');
background-repeat: no-repeat;
background-position: 95% 10%;
}
.btnAll span {
color: #000;
font-size: 130%;
}
.btnAll div {
margin-top: 30px;
}
/* hover shadow */
.btn, .btnAll, input {
transition: box-shadow .3s;
}
.btn:hover, .btnAll:hover, input:hover, input:focus-visible {
box-shadow: 0 0 10px rgba(33,33,33,.3);
}
/* fade-in */
.hidden {
opacity: 0;
}
.fade {
animation: fade .3s;
}
@keyframes fade {
0% {opacity: 0;}
100% {opacity: 1;}
}
35 changes: 35 additions & 0 deletions van/index.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<html>
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RG226NDPQM"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-RG226NDPQM');
</script>
<meta charset='utf-8'>
<title>Vancouver Classifieds MultiSearch</title>
<link href='../style.css' rel='stylesheet'>
</head>
<body>
<header></header>
<main>
<h1>MultiSearch</h1>
<h2>Vancouver, BC Classifieds</h2>
<form method='get'>
<input id='search' name='q' value=''>
<input type='submit' value='Search'>
<div></div>
</form>
</main>
<footer></footer>
<script>
const sites = [
['FB Marketplace','https://www.facebook.com/marketplace/vancouver/search/?query='],
['Craigslist','https://vancouver.craigslist.org/search/sss?purveyor=owner&query='],
['Kijiji','https://www.kijiji.ca/b-vancouver/', '/k0l1700287']
];
</script>
<script type='module' src='../script.js'></script>
</body>
</html>
Loading

0 comments on commit 28ce635

Please sign in to comment.