Compare commits
19 commits
Author | SHA1 | Date | |
---|---|---|---|
001a361037 | |||
dbf57bea46 | |||
bd1d3a5e2e | |||
5099cd92a5 | |||
aacb05aee2 | |||
1faf17e67f | |||
dcc607df51 | |||
ba7df6c13e | |||
1237e84670 | |||
5c111f86d7 | |||
f216b42011 | |||
ec902d12f2 | |||
004c92b392 | |||
7acd5f4e38 | |||
8efbafef3c | |||
c12f8220f4 | |||
39138ef889 | |||
e821501f6c | |||
98d8c3b994 |
7 changed files with 41 additions and 21 deletions
|
@ -1,9 +1,10 @@
|
||||||
# Mastowall 1.1
|
# Mastowall 1.1
|
||||||
|
|
||||||
|
Forked from [https://github.com/rstockm/mastowall](https://github.com/rstockm/mastowall)
|
||||||
|
|
||||||
Mastowall is a social wall application that displays posts from the [Mastodon](https://joinmastodon.org/) social network based on specified hashtags. It was written entirely by [ChatGPT4](https://openai.com/product/gpt-4), guided only by text prompts.
|
Mastowall is a social wall application that displays posts from the [Mastodon](https://joinmastodon.org/) social network based on specified hashtags. It was written entirely by [ChatGPT4](https://openai.com/product/gpt-4), guided only by text prompts.
|
||||||
|
|
||||||
<img width="1348" alt="image" src="https://github.com/rstockm/mastowall/assets/3195116/7060536e-4847-4e38-801e-3c0312b8b194">
|
<img width="1348" alt="image" src="https://git.verdigado.com/NB-Public/mastowall/raw/branch/main/screenshot.jpg">
|
||||||
|
|
||||||
|
|
||||||
Try it live: [Mastowall for BDK23](https://tretkowski.de/mastowall/?hashtags=bdk23,netzbegruenung&server=https://gruene.social)
|
Try it live: [Mastowall for BDK23](https://tretkowski.de/mastowall/?hashtags=bdk23,netzbegruenung&server=https://gruene.social)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"refreshDuration": 30,
|
"refreshDuration": 30,
|
||||||
"maxAge": 604800,
|
"maxAge": 604800,
|
||||||
"extraCards": [
|
"extraCards": [
|
||||||
"<img src='sharepic.jpg' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>"
|
"<img src='sharepic.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>"
|
||||||
],
|
],
|
||||||
"includeReplies": true
|
"includeReplies": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="hashtag2">Hashtag 2:</label>
|
<label for="hashtag2">Hashtag 2:</label>
|
||||||
<input type="text" class="form-control" id="hashtag2" placeholder="Enter a hashtag" value="bdk23">
|
<input type="text" class="form-control" id="hashtag2" placeholder="Enter a hashtag" value="ldk24">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="hashtag3">Hashtag 3:</label>
|
<label for="hashtag3">Hashtag 3:</label>
|
||||||
<input type="text" class="form-control" id="hashtag3" placeholder="Enter a hashtag">
|
<input type="text" class="form-control" id="hashtag3" placeholder="Enter a hashtag" value="wasjetztzählt">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="serverUrl">Server:</label>
|
<label for="serverUrl">Server:</label>
|
||||||
|
|
BIN
screenshot.jpg
Normal file
BIN
screenshot.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 410 KiB |
41
script.js
41
script.js
|
@ -77,7 +77,7 @@ const fetchConfig = async function() {
|
||||||
duration = 10000;
|
duration = 10000;
|
||||||
refresh = 30000;
|
refresh = 30000;
|
||||||
extraCards = [
|
extraCards = [
|
||||||
"<div><img src='sharepic.jpg' style='max-width: 100%;max-height: 100%'></div>"
|
"<div><img src='sharepic.png' style='max-width: 100%;max-height: 100%'></div>"
|
||||||
];
|
];
|
||||||
return "https://gruene.social";
|
return "https://gruene.social";
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,14 @@ const updateTimesOnPage = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// replace certain emojies in some text with images
|
||||||
|
const replaceEmojies = (text, emojis) => {
|
||||||
|
emojis.forEach(emoji => {
|
||||||
|
text = text.replaceAll(`:${emoji.shortcode}:`, `<img class="emoji" src="${emoji.static_url}">`);
|
||||||
|
});
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
// displayPost creates and displays a post
|
// displayPost creates and displays a post
|
||||||
const displayPost = function(post) {
|
const displayPost = function(post) {
|
||||||
if (existingPosts.includes(post.id) || (!includeReplies && post.in_reply_to_id !== null)) return 0;
|
if (existingPosts.includes(post.id) || (!includeReplies && post.in_reply_to_id !== null)) return 0;
|
||||||
|
@ -115,10 +123,14 @@ const displayPost = function(post) {
|
||||||
<div class="card m-2 p-2">
|
<div class="card m-2 p-2">
|
||||||
<div class="d-flex align-items-center mb-2">
|
<div class="d-flex align-items-center mb-2">
|
||||||
<img src="${post.account.avatar}" class="avatar-img rounded-circle mr-2">
|
<img src="${post.account.avatar}" class="avatar-img rounded-circle mr-2">
|
||||||
<p class="m-0">${DOMPurify.sanitize(post.account.display_name)} <span class="user-name">@${DOMPurify.sanitize(post.account.acct)}</span></p>
|
<p class="m-0">${replaceEmojies(DOMPurify.sanitize(post.account.display_name), post.account.emojis)} <span class="user-name">@${DOMPurify.sanitize(post.account.acct)}</span></p>
|
||||||
</div>
|
</div>
|
||||||
${post.media_attachments[0] ? `<img src="${post.media_attachments[0].url}" class="card-img-top mb-2">` : ''}
|
${post.media_attachments[0] ?
|
||||||
<p class="card-text">${DOMPurify.sanitize(post.content)}</p>
|
(post.media_attachments[0].url.endsWith('.mp4') ?
|
||||||
|
`<video src="${post.media_attachments[0].url}" controls autoplay muted loop></video>` :
|
||||||
|
`<img src="${post.media_attachments[0].url}" class="card-img-top mb-2">`) :
|
||||||
|
''}
|
||||||
|
<p class="card-text">${replaceEmojies(DOMPurify.sanitize(post.content), post.emojis)}</p>
|
||||||
${post.spoiler_text ? `<p class="card-text text-muted spoiler">${DOMPurify.sanitize(post.spoiler_text)}</p>` : ''}
|
${post.spoiler_text ? `<p class="card-text text-muted spoiler">${DOMPurify.sanitize(post.spoiler_text)}</p>` : ''}
|
||||||
<p class="card-text text-right"><small class="text-muted"><a class="time" href="${post.url}" target="_blank" data-time="${post.created_at}">${timeAgo(secondsAgo(new Date(post.created_at)))}</a></small></p>
|
<p class="card-text text-right"><small class="text-muted"><a class="time" href="${post.url}" target="_blank" data-time="${post.created_at}">${timeAgo(secondsAgo(new Date(post.created_at)))}</a></small></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -185,17 +197,22 @@ const updateCarousel = function(slides, posts) {
|
||||||
else {
|
else {
|
||||||
newHTML += `<div class="carousel-item" data-interval="${duration}" data-pause="false">`;
|
newHTML += `<div class="carousel-item" data-interval="${duration}" data-pause="false">`;
|
||||||
}
|
}
|
||||||
const postContent = DOMPurify.sanitize(post.content);
|
const postContent = replaceEmojies(DOMPurify.sanitize(post.content), post.emojis);
|
||||||
newHTML += `
|
newHTML += `
|
||||||
<div class="card-big">
|
<div class="card-big">
|
||||||
<div class="d-flex align-items-center mb-4">
|
<div class="d-flex align-items-center mb-4">
|
||||||
<img src="${post.account.avatar}" class="avatar-img-big rounded-circle mr-4">
|
<img src="${post.account.avatar}" class="avatar-img-big rounded-circle mr-4">
|
||||||
<p class="avatar-name">${DOMPurify.sanitize(post.account.display_name)} <span class="user-name">@${DOMPurify.sanitize(post.account.acct)}</span></p>
|
<p class="avatar-name">${replaceEmojies(DOMPurify.sanitize(post.account.display_name), post.account.emojis)} <span class="user-name">@${DOMPurify.sanitize(post.account.acct)}</span></p>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row align-items-center vertical-align-center">
|
<div class="row align-items-center vertical-align-center">
|
||||||
<div class="${post.media_attachments[0] ? `col-md-6` : `col-md-12`}"><div class="card-text" ${strip(postContent).length > 800 ? `style="font-size: 0.9em;"`: ``}>${postContent}</div></div>
|
<div class="${post.media_attachments[0] ? `col-md-6` : `col-md-12`}"><div class="card-text" ${strip(postContent).length > 700 ? `style="font-size: ${strip(postContent).length > 1000 ? `0.5`:`0.9`}em;"`: ``}>${postContent}</div></div>
|
||||||
${post.media_attachments[0] ? `<div class="col-md-6"><img src="${post.media_attachments[0].url}" class="card-img-bottom" align="center"> </div>` : ''}
|
${post.media_attachments[0] ?
|
||||||
|
(post.media_attachments[0].url.endsWith('.mp4') ?
|
||||||
|
`<div class="col-md-6"><video src="${post.media_attachments[0].url}" controls autoplay muted loop class="card-img-bottom" align="center"></video></div>` :
|
||||||
|
`<div class="col-md-6"><img src="${post.media_attachments[0].url}" class="card-img-bottom" align="center"> </div>`) :
|
||||||
|
''}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<p class="card-text text-right">
|
<p class="card-text text-right">
|
||||||
|
@ -210,7 +227,7 @@ const updateCarousel = function(slides, posts) {
|
||||||
newHTML += '</div>';
|
newHTML += '</div>';
|
||||||
}
|
}
|
||||||
for( let i = 0; i < extraCards.length; i++ ) {
|
for( let i = 0; i < extraCards.length; i++ ) {
|
||||||
newHTML += `<div class="carousel-item" data-mdb-interval="${duration * 2}" data-mdb-pause="false">
|
newHTML += `<div class="carousel-item" data-interval="${duration * 2}" data-pause="false">
|
||||||
<div className="card-big">
|
<div className="card-big">
|
||||||
<div class="d-flex align-items-center mb-4">
|
<div class="d-flex align-items-center mb-4">
|
||||||
${extraCards[i]}
|
${extraCards[i]}
|
||||||
|
@ -263,7 +280,7 @@ const handleHashtagDisplayClick = function(serverUrl) {
|
||||||
|
|
||||||
const currentHashtags = getUrlParameter('hashtags').split(',');
|
const currentHashtags = getUrlParameter('hashtags').split(',');
|
||||||
if ( currentHashtags = null ) {
|
if ( currentHashtags = null ) {
|
||||||
currentHasttags = "netzbegruenung,bdk23".split(',')
|
currentHasttags = "netzbegruenung,ldk24,wasjetztzählt".split(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < currentHashtags.length; i++) {
|
for (let i = 0; i < currentHashtags.length; i++) {
|
||||||
|
@ -314,7 +331,7 @@ $(document).ready(async function() {
|
||||||
|
|
||||||
let hashtags = getUrlParameter('hashtags');
|
let hashtags = getUrlParameter('hashtags');
|
||||||
if ( hashtags == '' ) {
|
if ( hashtags == '' ) {
|
||||||
hashtags = "netzbegruenung,bdk23";
|
hashtags = "netzbegruenung,lptsh,wasjetztzählt";
|
||||||
}
|
}
|
||||||
const hashtagsArray = hashtags ? hashtags.split(',') : [];
|
const hashtagsArray = hashtags ? hashtags.split(',') : [];
|
||||||
const serverUrl = getUrlParameter('server') || defaultServerUrl;
|
const serverUrl = getUrlParameter('server') || defaultServerUrl;
|
||||||
|
@ -341,9 +358,7 @@ $(document).ready(async function() {
|
||||||
const newPosts = await Promise.all(hashtagsArray.map(hashtag => fetchPosts(serverUrl, hashtag)));
|
const newPosts = await Promise.all(hashtagsArray.map(hashtag => fetchPosts(serverUrl, hashtag)));
|
||||||
let updated = updateWall(newPosts.flat());
|
let updated = updateWall(newPosts.flat());
|
||||||
if ( updated > 0 ) {
|
if ( updated > 0 ) {
|
||||||
hideCarousel()
|
|
||||||
updateCarousel(slides, newPosts.flat());
|
updateCarousel(slides, newPosts.flat());
|
||||||
setTimeout(async function() { showCarousel(); }, duration)
|
|
||||||
}
|
}
|
||||||
}, refresh);
|
}, refresh);
|
||||||
} else {
|
} else {
|
||||||
|
|
BIN
sharepic.png
Normal file
BIN
sharepic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 141 KiB |
10
styles.css
10
styles.css
|
@ -51,9 +51,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel .card-text {
|
.carousel .card-text {
|
||||||
font-size: 1.4em;
|
font-size: 1.6em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 60vh;
|
max-height: 50vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
|
@ -208,7 +208,7 @@ body {
|
||||||
|
|
||||||
.text-muted {
|
.text-muted {
|
||||||
color:#6c757d !important;
|
color:#6c757d !important;
|
||||||
font-size: 1.2em;
|
font-size: 1em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,3 +224,7 @@ body {
|
||||||
.footer a {
|
.footer a {
|
||||||
color: rgba(255, 255, 255, 0.8) !important;
|
color: rgba(255, 255, 255, 0.8) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
height: 1em;
|
||||||
|
}
|
Loading…
Reference in a new issue