-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
122 lines (111 loc) · 4.69 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Must lost post-its</title>
<style>
body {
background-color: #333333;
font-family: Arial, sans-serif;
text-align: center;
}
#search {
display: block;
width: calc(100% - 20px);
padding: 10px;
margin: 10px auto;
font-size: 16px;
border-radius: 5px;
border: none;
}
#postit-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 10px;
padding: 10px;
justify-content: center;
}
.post-it {
background-color: #f9f489;
padding: 15px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
border-radius: 5px;
text-align: left;
}
#loading {
color: #fff;
font-size: 20px;
margin-top: 20px;
}
.highlight {
background-color: yellow;
color: black;
}
</style>
</head>
<body>
<div id="loading">Loading...</div>
<input type="text" id="search" placeholder="Search post-its..." style="display:none;">
<div id="postit-container" style="display:none;"></div>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
fetch('/mundaneum/post-its.md')
.then(response => {
if (!response.ok) {
throw new Error('Failed to load the markdown file');
}
return response.text();
})
.then(text => {
const posts = marked.lexer(text).filter(item => item.type === 'paragraph').map(item => item.text);
initializePosts(posts);
document.getElementById('loading').style.display = 'none';
document.getElementById('search').style.display = 'block';
document.getElementById('postit-container').style.display = 'grid';
})
.catch(error => {
document.getElementById('loading').textContent = error.message;
});
function initializePosts(posts) {
const fuse = new Fuse(posts, {
includeScore: true,
includeMatches: true,
findAllMatches: false,
shouldSort: true,
threshold: 0.3,
ignoreLocation: true,
});
const searchInput = document.getElementById('search');
const container = document.getElementById('postit-container');
searchInput.addEventListener('input', function() {
const results = searchInput.value ? fuse.search(searchInput.value) : posts.map(post => ({ item: post }));
displayPostsSearch(results);
});
displayPosts(posts); // display all posts initially
function displayPosts(posts) {
container.innerHTML = posts.map(post => `<div class="post-it">${post.replace(/\n/g, '<br>')}</div>`).join('');
}
function displayPostsSearch(results) {
container.innerHTML = results.map(result => {
let highlightedText = result.item;
if (result.matches && result.matches.length > 0) {
// Find the largest match
const largestMatch = result.matches[0].indices.reduce((largest, current) => {
return (current[1] - current[0] > largest[1] - largest[0]) ? current : largest;
}, [0, 0]);
// Highlight the largest match
highlightedText = `${highlightedText.substring(0, largestMatch[0])}` +
`<span class="highlight">${highlightedText.substring(largestMatch[0], largestMatch[1] + 1)}</span>` +
`${highlightedText.substring(largestMatch[1] + 1)}`;
}
return `<div class="post-it">${highlightedText.replace(/\n/g, '<br>')}</div>`;
}).join('');
}
}
});
</script>
</body>
</html>