mirror of
https://github.com/arfct/itty-bitty.git
synced 2026-03-11 08:54:33 +00:00
Update history
This commit is contained in:
parent
ffb694d3a1
commit
76249232dd
2 changed files with 198 additions and 96 deletions
117
docs/history.css
Normal file
117
docs/history.css
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
* {
|
||||
font-family: sans-serif;
|
||||
font-size: 13px;
|
||||
--secondary-text-color: rgba(0,0,0,0.54)
|
||||
}
|
||||
body {
|
||||
background-color: #f1f1f1;
|
||||
margin: 4vw;
|
||||
background-image:
|
||||
linear-gradient(45deg,rgba(128,128,128,.5) 25%,transparent 25%),
|
||||
linear-gradient(-45deg,rgba(128,128,128,.5) 25%,transparent 25%),
|
||||
linear-gradient(45deg,transparent 75%,rgba(128,128,128,.5) 75%),
|
||||
linear-gradient(-45deg,transparent 75%,rgba(128,128,128,.5) 75%);
|
||||
background-size: 4px 4px;
|
||||
background-position: 0 0,0 2px,2px -2px,-2px 0;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
}
|
||||
input {
|
||||
border: 2px solid #000;
|
||||
border-bottom: 2px solid #000;
|
||||
width: 50%;
|
||||
font-size: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 26px;
|
||||
padding: .5em 1em;
|
||||
box-shadow: 2px 2px #000;
|
||||
margin: auto auto 1em
|
||||
}
|
||||
#results {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center
|
||||
}
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
margin: .5em;
|
||||
position: relative;
|
||||
width: 15em;
|
||||
height: 17em;
|
||||
max-width: 68vmin;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
justify-content: space-between;
|
||||
border: 2px solid currentColor;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 2px 2px 0 #000
|
||||
}
|
||||
a:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
right: -4px;
|
||||
border-width: 0 16px 16px 0;
|
||||
border-style: solid;
|
||||
border-color: #000 #f1f1f1;
|
||||
display: none
|
||||
}
|
||||
a:hover {
|
||||
background-color: #fafafa
|
||||
}
|
||||
a:hover .preview {
|
||||
opacity: .8
|
||||
}
|
||||
a .preview {
|
||||
width: 100%;
|
||||
height: 0%;
|
||||
flex: 1 1 auto;
|
||||
padding-top: 61.8%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
margin-top: 1em
|
||||
}
|
||||
div.delete {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
position: absolute;
|
||||
top: -.5em;
|
||||
right: -.5em;
|
||||
background-color: #fff;
|
||||
border: 2px solid #000;
|
||||
border-radius: 1em;
|
||||
content: 'x';
|
||||
text-align: center;
|
||||
line-height: .9em;
|
||||
z-index: 100
|
||||
}
|
||||
a:not(:hover) div.delete {
|
||||
display: none
|
||||
}
|
||||
.info {
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
padding: 1em 1em 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 4;
|
||||
line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.25em;
|
||||
flex-grow: 0
|
||||
}
|
||||
.emoji {
|
||||
font-size: 48px;
|
||||
margin: .2em
|
||||
}
|
||||
.title {
|
||||
font-weight: 700
|
||||
}
|
||||
.desc {
|
||||
color: var(--secondary-text-color)
|
||||
}
|
||||
|
|
@ -5,73 +5,22 @@
|
|||
<meta name="viewport" content="width=device-width, viewport-fit=cover">
|
||||
<meta name="description" content="itty bitty history">
|
||||
<script src="js/util.js"></script>
|
||||
<style>
|
||||
* {
|
||||
font-family: sans-serif;
|
||||
font-size:13px;
|
||||
}
|
||||
body {
|
||||
display:flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
a {
|
||||
display:inline-block;
|
||||
text-decoration:none;
|
||||
color:black;
|
||||
margin:1em;
|
||||
position:relative;
|
||||
width:200px;
|
||||
min-height:200px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
||||
border-radius:4px;
|
||||
}
|
||||
<link rel="stylesheet" href="history.css">
|
||||
|
||||
a:hover {
|
||||
background-color:#fafafa;
|
||||
}
|
||||
|
||||
a:hover .preview {
|
||||
opacity:0.8;
|
||||
}
|
||||
a .preview {
|
||||
width:100%;
|
||||
padding-top:61.8%;
|
||||
background-size:cover;
|
||||
background-position:center;
|
||||
}
|
||||
div.delete {
|
||||
width:1em;
|
||||
height:1em;
|
||||
background-color:orange;
|
||||
position:absolute;
|
||||
top: -.5em;
|
||||
right: -.5em;
|
||||
background-color:white;
|
||||
border:2px solid black;
|
||||
border-radius:1em;
|
||||
content:'x';
|
||||
text-align:center;
|
||||
line-height:0.9em;
|
||||
}
|
||||
<body>
|
||||
<input id="search" type="search" placeholder="search"></input>
|
||||
<div id="results"></div>
|
||||
|
||||
a:not(:hover) div.delete {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding:1em;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
</body>
|
||||
<script type="module">
|
||||
import * as bitty from './bitty.js';
|
||||
|
||||
navigator.storage.persist().then(function(persistent) {
|
||||
console.log("persist", persistent) ;
|
||||
})
|
||||
|
||||
|
||||
|
||||
let openRequest = indexedDB.open("history", 1);
|
||||
let openRequest = indexedDB.open("history", 3);
|
||||
|
||||
openRequest.onupgradeneeded = function() {
|
||||
// let db = openRequest.result;
|
||||
|
|
@ -85,64 +34,100 @@ openRequest.onerror = function() {
|
|||
};
|
||||
|
||||
|
||||
function firstValidString(...args) {
|
||||
for (let i in args) {
|
||||
let s = args[i]
|
||||
if (s && s.length) return s;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteHistoryItem(key) {
|
||||
let db = openRequest.result;
|
||||
console.log("db", db);
|
||||
console.log("db", db, key);
|
||||
|
||||
let transaction = db.transaction("history", "readwrite"); // (1)
|
||||
let history = transaction.objectStore("history"); // (2)
|
||||
let transaction = db.transaction("urls", "readwrite"); // (1)
|
||||
let history = transaction.objectStore("urls"); // (2)
|
||||
|
||||
document.getElementById(key).remove()
|
||||
history.delete(key);
|
||||
// location.reload();
|
||||
}
|
||||
|
||||
openRequest.onsuccess = function() {
|
||||
let db = openRequest.result;
|
||||
console.log("db", db);
|
||||
|
||||
let transaction = db.transaction("history", "readwrite"); // (1)
|
||||
let history = transaction.objectStore("history"); // (2)
|
||||
|
||||
|
||||
// get all books
|
||||
history.getAll()
|
||||
|
||||
let request = history.index('created').openCursor();
|
||||
|
||||
// called for each book found by the cursor
|
||||
request.onsuccess = function() {
|
||||
let cursor = request.result;
|
||||
const renderResults = (e) => {
|
||||
let cursor = e.target.result;
|
||||
console.log("curs", cursor)
|
||||
if (cursor) {
|
||||
try {
|
||||
let key = cursor.key; // book key (id field)
|
||||
let value = cursor.value; // book object
|
||||
let url = new URL(key);
|
||||
let path = url.pathname.split("/");
|
||||
console.log(path)
|
||||
path.shift()
|
||||
let title = path.shift().replace(/_/g, " ");
|
||||
let description = path.shift();
|
||||
let image = path.join("/");
|
||||
let emoji = image.startsWith("http") ? null : decodeURIComponent(image);
|
||||
console.log(key, value);
|
||||
console.log("image", decodeURIComponent(image));
|
||||
document.body.appendChild(
|
||||
m('a', {href:key, id:key},
|
||||
m('div.emoji', emoji),
|
||||
m('div.preview', {style:"background-image:url(" + image + ")"}),
|
||||
m('div.delete', {onclick: (e) => {e.stopPropagation(); e.preventDefault(); deleteHistoryItem(key); return false;}}, "×"),
|
||||
m('div.title', title),
|
||||
m('div.desc', description)));
|
||||
console.log("key", key, value)
|
||||
let url = new URL(value.url);
|
||||
let parseInfo = bitty.parseBittyURL(url);
|
||||
|
||||
let info = bitty.pathToMetadata(parseInfo.path);
|
||||
|
||||
let title = firstValidString(info.title, parseInfo.hashTitle, value.title, parseInfo.hashData);
|
||||
let description = info.d
|
||||
console.log("info", info);
|
||||
let image = info.i ? atob(info.i.replace(/=/g,'')) : null;
|
||||
// let image = path.join("/");
|
||||
// let emoji = image.startsWith("http") ? null : decodeURIComponent(image);
|
||||
|
||||
document.getElementById("results").appendChild(
|
||||
m('a', {href:url, id:value.id, target:"_blank", title:title},
|
||||
m('div.delete', {onclick: (e) => {e.stopPropagation(); e.preventDefault(); deleteHistoryItem(value.id); return false;}}, "×"),
|
||||
m('div.info',
|
||||
m('span.title', title),m('br'),
|
||||
m('span.desc', value.text || description)
|
||||
),
|
||||
image ?
|
||||
m('div.preview', {style:"background-image:url(" + image + ")"})
|
||||
: m('div.emoji', info.f),
|
||||
|
||||
)
|
||||
)
|
||||
} catch (e) {console.log(e)}
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
|
||||
openRequest.onsuccess = function() {
|
||||
let db = openRequest.result;
|
||||
console.log("db", db);
|
||||
|
||||
let transaction = db.transaction("urls", "readwrite"); // (1)
|
||||
let objectStore = transaction.objectStore("urls"); // (2)
|
||||
|
||||
|
||||
// get all books
|
||||
document.getElementById("results").innerHTML = ""
|
||||
|
||||
objectStore.getAll()
|
||||
let request = objectStore.index('created').openCursor();
|
||||
|
||||
// called for each book found by the cursor
|
||||
request.onsuccess = renderResults;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
document.getElementById("search").oninput = (e) => {
|
||||
let query = e.target.value;
|
||||
let db = openRequest.result;
|
||||
|
||||
let transaction = db.transaction("urls", "readwrite"); // (1)
|
||||
let objectStore = transaction.objectStore("urls"); // (2)
|
||||
|
||||
document.getElementById("results").innerHTML = ""
|
||||
objectStore.getAll()
|
||||
|
||||
let request = objectStore.openCursor(IDBKeyRange.only(query));
|
||||
request.onerror = (e) => console.log("err", e)
|
||||
request.onsuccess = renderResults;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue