fuzzy-searching, parallax

This commit is contained in:
James Shiffer 2020-06-22 21:23:44 -07:00
parent 5a1467c971
commit 817057a861
No known key found for this signature in database
GPG Key ID: C0DB8774A1B3BA45
10 changed files with 144 additions and 16 deletions

5
package-lock.json generated
View File

@ -2736,6 +2736,11 @@
}
}
},
"mongoose-fuzzy-searching": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/mongoose-fuzzy-searching/-/mongoose-fuzzy-searching-1.3.1.tgz",
"integrity": "sha512-Vi+EwmYPoxZzgwBOuTg5FBjXqbX1gjbXxvX/4Ypo7yC2aGKwKfgEeenAVwU6DPirL/TDj6jLGEoblzMJ3+HWCg=="
},
"mongoose-legacy-pluralize": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",

View File

@ -21,6 +21,7 @@
"express": "^4.17.1",
"express-session": "^1.17.1",
"mongoose": "^5.9.18",
"mongoose-fuzzy-searching": "^1.3.1",
"multer": "^1.4.2",
"passport": "^0.4.1",
"passport-local": "^1.0.0",

View File

@ -1,6 +1,15 @@
<script>
import { stores } from '@sapper/app';
import { stores, goto } from '@sapper/app';
const { session } = stores();
let query = '';
function search(e)
{
if (e.keyCode === 13) {
goto(`/search/${encodeURIComponent(query)}`);
}
}
</script>
<style>
@ -23,11 +32,10 @@
padding: 0 1.5rem 0.25rem;
align-items: start;
}
div.filler {
div.search {
flex: 1 0 0;
}
div.items div {
display: block;
margin: auto 0;
display: flex;
}
div.link a {
text-decoration: none;
@ -48,12 +56,21 @@
margin-left: 4rem;
}
}
input.search {
height: 1.5rem;
width: 50%;
font-size: 1rem;
margin: 0 auto;
text-align: center;
}
</style>
<nav>
<div class="items">
<div><a href="/"><img class="wordmark" src="/logo.png" alt="HowFeed.biz"></a></div>
<div class="filler"></div>
<div class="search">
<input class="search" on:keyup={search} bind:value={query} type="text" placeholder="Search">
</div>
{#if !$session.user}
<div class="link"><a href="/contact">Contact Us</a></div>
{:else}

View File

@ -1,4 +1,5 @@
import mongoose from 'mongoose';
import mongoose_fuzzy_searching from 'mongoose-fuzzy-searching';
const { Schema } = mongoose;
const ArticleSchema = new Schema({
@ -28,13 +29,18 @@ const ArticleSchema = new Schema({
ArticleSchema.methods.genSlug = title => title.toLowerCase().replace(/\W+/g, '-');
ArticleSchema.pre('save', function (next) {
var article = this;
// only gen the slug if title has been modified (or is new)
if (!article.isModified('title')) return next();
ArticleSchema.plugin(mongoose_fuzzy_searching, {
fields: ['html', 'title'],
middlewares: {
preSave: function () {
var article = this;
// only gen the slug if title has been modified (or is new)
if (!article.isModified('title'))
return;
article.slug = article.genSlug(article.title);
next();
article.slug = article.genSlug(article.title);
}
}
});
export default mongoose.model('Article', ArticleSchema);

View File

@ -83,7 +83,7 @@
async function addCategory()
{
let name = prompt('Enter a category name');
if (name) {
if (name !== null) {
const res = await fetch('/cms/category', {
method: 'POST',
headers: {
@ -92,8 +92,13 @@
},
body: JSON.stringify({ name })
});
categories = await res.json();
category = categories.filter(c => c.name === name)[0].slug;
const json = await res.json();
if (res.status === 200) {
categories = json;
category = categories.filter(c => c.name === name)[0].slug;
} else {
alert(`Error ${res.status}: ${json.message}`);
}
}
}
</script>

View File

@ -36,7 +36,7 @@
<h3>James N. Shiffer</h3>
<p>Webmaster</p>
<p>FemboyFinancial Holdings Co., Ltd. (USA LLC)</p>
<p><a href="mailto:webmaster@femboyfashion.com.hk">webmaster@femboyfashion.com.hk</a></p>
<p><a href="mailto:webmaster@howfeed.biz">webmaster@howfeed.biz</a></p>
</div>
</div>
<div style="max-width:100%;margin:0 auto;width:700px;height:440px;">

View File

@ -0,0 +1,55 @@
<script context="module">
export async function preload({ params })
{
let query = params.query;
const res = await this.fetch(`/search.json?query=${encodeURIComponent(query)}`);
const json = await res.json();
if (res.status === 200) {
return { query, results: json };
} else {
this.error(res.status, res.message);
}
}
</script>
<script>
export let query;
export let results;
</script>
<style>
h1 {
margin: 0 auto;
color: whitesmoke;
margin-top: 1rem;
font-size: 2rem;
font-size: 3rem;
text-transform: uppercase;
text-align: center;
max-width: 80%;
}
</style>
<svelte:head>
<title>Search Results for: {query} | HOWFEED.BIZ</title>
</svelte:head>
<div class="background"></div>
<div class="floaty">
<h1>Search Results for: {query}</h1>
<div class="article-list">
{#each results as {title, slug, image, created_at}}
<a rel="prefetch" href={`/a/${slug}`}>
<figure class="article-image">
<img src={image || '/logo.png'} alt={title}>
</figure>
<div class="article-meta">
<p class="article-title">{title}</p>
<p class="article-date">{new Date(created_at).toLocaleDateString()}</p>
</div>
</a>
{:else}
<p>No results found :(</p>
{/each}
</div>
</div>

View File

@ -0,0 +1,20 @@
import Article from '../../models/article.js';
export async function get(req, res)
{
const { query } = req.query;
if (!query) {
res.writeHead(422, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `No search query provided`
}));
return;
}
const results = await Article.fuzzySearch(query);
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(results));
}

View File

@ -0,0 +1,18 @@
<script>
import { goto } from '@sapper/app';
let query = '';
</script>
<style>
input {
width: 440px;
}
</style>
<div class="content">
<h1>Search Results</h1>
<p>You haven't entered any search terms.</p>
<input type="text" placeholder="Search Articles" bind:value={query}>
<button type="submit" on:click={() => { goto(`/search/${encodeURIComponent(query)}`); }}>Search</button>
</div>

View File

@ -115,6 +115,7 @@ div.article-meta {
div.background {
background: url('/cityscape.jpg') no-repeat center;
background-size: cover;
background-attachment: fixed;
position: fixed;
height: 24rem;
width: 100%;