Compare commits

...

81 commits
1.1 ... main

Author SHA1 Message Date
b23ad379c8
Do not display posts with content warning 2024-11-16 11:19:28 +01:00
6e5d649876 Merge pull request 'Update sharepics' (#8) from max.lissowski/mastowall:pr/new-sharepics into main
Reviewed-on: #8
Reviewed-by: Norbert Tretkowski <norbert@tretkowski.de>
2024-11-15 22:56:17 +01:00
Max
56d57e4255
Update sharepics 2024-11-15 22:52:59 +01:00
02fb2c023f Merge pull request 'script.js aktualisiert' (#7) from paulusr1/mastowall:main into main
Reviewed-on: #7
Reviewed-by: Norbert Tretkowski <norbert@tretkowski.de>
2024-11-15 19:05:09 +01:00
c9953a4e3b script.js aktualisiert
Make sure Carousel does not block links when disabled.
2024-11-15 12:05:15 +01:00
f52d2d2c25 Merge pull request 'main' (#6) from stefan.schmidt-bilkenroth/mastowall:main into main
Reviewed-on: #6
2024-11-15 11:12:01 +01:00
Stefan Schmidt-Bilkenroth
678e08e681 implement nbstand URL argument to enable carousel 2024-11-15 11:00:44 +01:00
Stefan Schmidt-Bilkenroth
973a3b9342 update Readme including nbstand=1 argument 2024-11-15 11:00:13 +01:00
49361092c9
Update Hashtags 2024-11-14 21:07:14 +01:00
6d579f4f45
Update Hashtags 2024-11-14 21:05:11 +01:00
001a361037
Revert "Fix fullscreen mode on iOS/iPadOS"
This reverts commit bd1d3a5e2e.
2024-10-09 06:33:28 +02:00
dbf57bea46
Update hashtag 2024-05-05 09:10:49 +02:00
bd1d3a5e2e
Fix fullscreen mode on iOS/iPadOS 2024-05-04 11:57:17 +02:00
5099cd92a5
Hashtag #wasjetztzählt hinzugefügt 2024-01-21 11:42:57 +01:00
aacb05aee2
Add support for displaying video attachments based on https://github.com/rstockm/mastowall/pull/10 2024-01-20 15:19:31 +01:00
1faf17e67f
Update screenshot in README.md 2024-01-20 13:29:50 +01:00
dcc607df51
Use jpg for screenshot 2024-01-20 13:28:25 +01:00
ba7df6c13e
Add screenshot 2024-01-20 13:27:16 +01:00
1237e84670
Update hashtags 2024-01-20 10:00:38 +01:00
5c111f86d7
Sharepic fuer LDK24 Potsdam 2024-01-20 09:58:54 +01:00
f216b42011 Merge pull request 'Even more improvements' (#5) from lisswoma/mastowall:for-pi2 into main
Reviewed-on: #5
2023-11-25 10:21:11 +01:00
ec902d12f2
Fix extra cards display duration 2023-11-25 02:21:55 +01:00
004c92b392
Add emoji support 2023-11-25 02:18:39 +01:00
7acd5f4e38
Improve long post handling 2023-11-25 01:48:53 +01:00
8efbafef3c
Directly show new posts in carousel 2023-11-25 01:13:05 +01:00
c12f8220f4
Improve font sizes 2023-11-25 01:08:41 +01:00
39138ef889 Merge pull request 'for-pi2' (#4) from for-pi2 into main
Reviewed-on: #4
2023-11-24 21:17:28 +01:00
945e09b3ac Merge pull request 'for-pi2' (#3) from lisswoma/mastowall:for-pi2 into for-pi2
Reviewed-on: #3
2023-11-24 21:14:11 +01:00
c274648f09
Fix duration not being used for carousel 2023-11-24 13:07:14 +01:00
876f2bb7ad
Try to deal better with overflow
ALso align images right in carousel
2023-11-24 12:45:28 +01:00
6f9459fb3e
Fix post content not being child of card-text 2023-11-24 12:26:44 +01:00
b0051867aa
Fix wrong links getting their time updated 2023-11-24 12:25:34 +01:00
12fca72480
Filter out duplicate carousel cards
Also respect reply config option in carousel
2023-11-24 12:08:19 +01:00
e821501f6c Link to original project on GitHub 2023-11-24 08:05:29 +01:00
98d8c3b994 Merge pull request 'for-pi2' (#2) from for-pi2 into main
Reviewed-on: #2
2023-11-24 07:54:18 +01:00
bcaa5a5edd Merge pull request 'Improvements for display' (#1) from lisswoma/mastowall:for-pi2 into for-pi2
Reviewed-on: #1
2023-11-24 07:53:18 +01:00
3ba54e1653
Display full account name 2023-11-23 22:06:42 +01:00
c76dfedac1
Filter out twitter repost spam 2023-11-23 21:57:58 +01:00
de46f7c7b8
Fix extra card interval 2023-11-23 21:06:54 +01:00
8cdc4ea5c3
Fix sorting in carousel 2023-11-23 20:57:33 +01:00
191dc33e28
Add gruene.social to title 2023-11-23 20:48:46 +01:00
9cab9e8b1c
Display username 2023-11-23 20:44:43 +01:00
df73c736dd
Fix singular of time ago display 2023-11-23 20:44:42 +01:00
3ffdeabf33
Add ability to display extra cards and add a post max age 2023-11-23 20:44:41 +01:00
395ce728bf
Fix footer colors and size 2023-11-23 20:44:40 +01:00
75d4e84e5c
Increase font size for display on a large screen 2023-11-23 20:44:39 +01:00
eb85222ea3
Make duration and refresh easily configurable
Also increase duration to 10 seconds per post
2023-11-23 20:44:38 +01:00
7edce5ab0f add 5 seconds sleep before opening mastowll 2023-11-18 20:53:58 +01:00
038546df49 move mouse to bottom right on startup 2023-11-18 20:53:12 +01:00
65d9454666 fix typo 2023-11-16 18:07:43 +01:00
ec6c88d83e fix pause on mouse-over 2023-11-16 18:01:30 +01:00
53f5b71b32 adding Autostart file 2023-11-16 17:13:03 +01:00
5b2d634bf0 fixes for raspi 2023-11-16 16:22:59 +01:00
06080e09a1 fix some startup issues, default to BDK config 2023-11-16 16:14:06 +01:00
c951f47034 beantwortet -> kommentiert 2023-11-16 14:51:31 +01:00
7969da352a fixed small typo 2023-11-16 14:50:20 +01:00
1f6d85a072 some more refinements 2023-11-16 14:47:37 +01:00
515aa7f86c added specific ReadMe 2023-11-16 12:32:40 +01:00
752f06f68f some fixes 2023-11-16 12:18:48 +01:00
63d5eafc01 fix issue with startup form (covered by invisible popup) 2023-11-10 20:35:20 +01:00
4c527ec4c4 small optimization 2023-11-10 19:59:46 +01:00
a4891e24bb some more work 2023-11-10 19:42:57 +01:00
65438d8799 stuff 2023-11-10 17:17:00 +01:00
42f41cc360 new attempts 2023-11-10 17:16:31 +01:00
73163da9ec Update link 2023-11-05 17:36:04 +01:00
3f28ac8ad2 Add default hashtags and server 2023-11-05 17:29:01 +01:00
9d07ff6a63 Tippfehler 2023-11-05 11:36:50 +01:00
32068def92 Update Demo Link 2023-11-05 11:11:33 +01:00
8dde3b2827 Branding und Übersetzung 2023-11-05 10:55:58 +01:00
Ralf Stockmann
a043940301
Merge pull request #5 from optikfluffel/show-hashtags-in-title
Show hashtags in the page title
2023-06-07 13:12:28 +02:00
Udo
f0b2e205d9 Show hashtags in the page title 2023-06-05 12:23:01 +02:00
Ralf Stockmann
34ff6c48bd
Update README.md
WWDC demo
2023-06-05 09:40:58 +02:00
Ralf Stockmann
abdd8a83de
Add files via upload
White Background
2023-05-29 17:20:07 +02:00
Ralf Stockmann
b2f7055164
Delete mastowall-favicon.png 2023-05-29 17:19:48 +02:00
Ralf Stockmann
a9c4621eff
New version of Favicon
More space around the # - thx to @malik
2023-05-29 10:51:51 +02:00
Ralf Stockmann
9f82492a96
Delete mastowall-favicon.png 2023-05-29 10:51:08 +02:00
Ralf Stockmann
321bb89b33
Add files via upload
More space to borders, thx to @malik
2023-05-29 10:50:13 +02:00
Ralf Stockmann
36eb5bc1db
Update index.html
HiRes Favicon
2023-05-28 21:27:54 +02:00
Ralf Stockmann
afb2eb06e8
HiRes Favicon 2023-05-28 21:26:25 +02:00
Ralf Stockmann
1c28ce654d
Update README.md
Added 1.1 config screen
2023-05-26 10:26:57 +02:00
Ralf Stockmann
ed73ee845a
Update README.md
- Added 1.1 Screenshot
2023-05-26 10:26:08 +02:00
15 changed files with 11616 additions and 48 deletions

View file

@ -1,14 +1,16 @@
# 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.
<img width="1435" alt="image" src="https://github.com/rstockm/mastowall/assets/3195116/af1a3786-335b-4d64-b387-0db75dd73040">
<img width="1348" alt="image" src="https://git.verdigado.com/NB-Public/mastowall/raw/branch/main/screenshot.jpg">
Try it live: [Mastowall for the BiblioCon conference](https://rstockm.github.io/mastowall/?hashtags=111bibliocon,bibliocon,bibliocon23&server=https://openbiblio.social))
Try it live: [Mastowall for BDK23](https://tretkowski.de/mastowall/?hashtags=bdk23,netzbegruenung&server=https://gruene.social)
Use your own hashtags and server:
<img width="1164" alt="image" src="https://github.com/rstockm/mastowall/assets/3195116/97814e5b-5377-426a-bfff-78be8f560421">
<img width="1108" alt="image" src="https://github.com/rstockm/mastowall/assets/3195116/761237da-2166-46c5-8f31-46b9e913f736">
JSON config file:
@ -36,6 +38,8 @@ JSON config file:
- **Including Replies:** By default, replies are excluded from the wall. However, this behavior can be changed by setting includeReplies to true in the `config.json` file.
- **Configurable Overlay:** By default only the MastoWall is shown. For use with large displays eg during trade shows, conferences, booths, you can enable the Carousel with enlarged display of the 10 most recent posts. Just add `nbstand=1` to the argument in the URL.
## Technology Stack
Mastowall is built using the following technologies:
@ -62,7 +66,7 @@ Mastowall is built using the following technologies:
## Sharing via URL
Mastowall supports URL parameters to easily share specific hashtag configurations and the Mastodon server. Simply append the desired hashtags and the server URL to the URL following this format: `?hashtags=hashtag1,hashtag2,hashtag3&server=serverUrl`
Mastowall supports URL parameters to easily share specific hashtag configurations and the Mastodon server. Simply append the desired hashtags and the server URL to the URL following this format: `?hashtags=hashtag1,hashtag2,hashtag3&server=serverUrl&nbstand=0`
Enjoy using Mastowall!

16
README_SSB.md Normal file
View file

@ -0,0 +1,16 @@
## Additions made by SSB for BDK23
# added carousel for posts
## Important
install color emojis:
sudo apt-get install fonts-noto-color-emoji
install xdotool to move the mouse to bottom right (does not work with Bookworm/Wayland)
sudo apt-get install xdotool -y
run in kiosk mode:
chromium-browser --kiosk index.html
or use the remote URL instead of index.html

10159
bootstrap.min.css vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,15 @@
{
"navbarBrandText": "Mastowall 1.1 - written by ChatGPT4 - Prompting: Ralf Stockmann (rstockm)",
"defaultServerUrl": "https://mastodon.social",
"navbarColor": "#333355",
"navbarBrandText": "Netzbegrünung Mastowall - gruene.social",
"defaultServerUrl": "https://gruene.social",
"navbarColor": "#008939",
"duration": 10,
"refreshDuration": 30,
"maxAge": 604800,
"extraCards": [
"<img src='sharepics/Slide1.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide2.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide3.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide4.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>"
],
"includeReplies": true
}

View file

@ -3,9 +3,21 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mastowall 1.1</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<title>Netzbegrünung Mastowall</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<link rel="apple-touch-icon" href="mastowall-favicon.png">
<link rel="icon" href="mastowall-favicon.png" type="image/x-icon">
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.4/imagesloaded.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.3/purify.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<nav class="navbar navbar-light">
@ -22,19 +34,19 @@
<form id="hashtag-form">
<div class="form-group">
<label for="hashtag1">Hashtag 1:</label>
<input type="text" class="form-control" id="hashtag1" placeholder="Enter a hashtag">
<input type="text" class="form-control" id="hashtag1" placeholder="Enter a hashtag" value="netzbegruenung">
</div>
<div class="form-group">
<label for="hashtag2">Hashtag 2:</label>
<input type="text" class="form-control" id="hashtag2" placeholder="Enter a hashtag">
<input type="text" class="form-control" id="hashtag2" placeholder="Enter a hashtag" value="bdk24">
</div>
<div class="form-group">
<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 class="form-group">
<label for="serverUrl">Server:</label>
<input type="text" class="form-control" id="serverUrl" placeholder="Enter server URL" value="https://mastodon.social">
<input type="text" class="form-control" id="serverUrl" placeholder="Enter server URL" value="https://gruene.social">
</div>
<button type="submit" class="btn btn-primary">Reload</button>
@ -48,17 +60,17 @@
<div class="row masonry-grid" id="wall"></div>
</div>
<div id="popover" class="popover">
<div id="myCarousel" class="carousel slide" data-mdb-ride="carousel" data-mdb-pause="false">
</div>
</div>
<footer class="footer text-center py-4 mt-5">
<div class="container">
<span class="text-muted">Host your own Mastowall - check </span>
<a href="https://github.com/rstockm/mastowall" target="_blank">GitHub</a>
<a href="https://netzbegruenung.de/" target="_blank">Netzbegrünung</a>
<span class="text-muted"> - Verein für GRÜNE Netzkultur e.V.</span>
</div>
</footer>
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.4/imagesloaded.pkgd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.3/purify.min.js"></script>
<script src="script.js"></script>
</body>
</html>

1069
masonry.pkgd.min.js vendored Normal file

File diff suppressed because it is too large Load diff

BIN
mastowall-favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

6
mastowall.desktop Normal file
View file

@ -0,0 +1,6 @@
[Desktop Entry]
Type=Application
Name=MastoWall Autostart
Comment=Starten der MastoWall zur BDK23
NoDisplay=false
Exec=sh -c 'cd /home/ssb/Documents/mastowall && xdotool mousemove 1920 1080 && sleep 5 && chromium-browser --kiosk index.html'

BIN
screenshot.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

250
script.js
View file

@ -6,6 +6,7 @@ function getUrlParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search);
console.log(results)
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
@ -16,23 +17,46 @@ const secondsAgo = date => Math.floor((new Date() - date) / 1000);
const timeAgo = function(seconds) {
// An array of intervals for years, months, days, hours, and minutes.
const intervals = [
{ limit: 31536000, text: 'years' },
{ limit: 2592000, text: 'months' },
{ limit: 86400, text: 'days' },
{ limit: 3600, text: 'hours' },
{ limit: 60, text: 'minutes' }
{ limit: 31536000, singular: 'Jahre', plural: 'Jahren' },
{ limit: 2592000, singular: 'Monat', plural: 'Monaten' },
{ limit: 86400, singular: 'Tag', plural: 'Tagen' },
{ limit: 3600, singular: 'Stunde', plural: 'Stunden' },
{ limit: 60, singular: 'Minute', plural: 'Minuten' }
];
// Loop through the intervals to find which one is the best fit.
for (let interval of intervals) {
if (seconds >= interval.limit) {
return Math.floor(seconds / interval.limit) + ` ${interval.text} ago`;
let amount = Math.floor(seconds / interval.limit);
let text;
if (amount !== 1) {
text = interval.plural;
} else {
text = interval.singular;
}
return `Vor ${amount} ${text}`;
}
}
return Math.floor(seconds) + " seconds ago";
let text = "Sekunde";
let amount = Math.floor(seconds);
if (amount !== 1) {
text += "n";
}
return `Vor ${amount} ${text}`;
};
let includeReplies;
// max post age in seconds
let maxAge;
// below times are in milliseconds
// duration for slide animations
let duration;
// refresh rate
let refresh;
// extra cards text
let extraCards;
// toggle Carousel
let withCarousel=false;
// fetchConfig fetches the configuration from the config.json file
const fetchConfig = async function() {
@ -41,9 +65,26 @@ const fetchConfig = async function() {
$('#navbar-brand').text(config.navbarBrandText);
$('.navbar').css('background-color', config.navbarColor);
includeReplies = config.includeReplies;
maxAge = config.maxAge;
duration = config.duration * 1000;
refresh = config.refreshDuration * 1000;
extraCards = config.extraCards;
return config.defaultServerUrl;
} catch (error) {
console.error("Error loading config.json:", error);
console.log("Error loading config.json:", error);
$('#navbar-brand').text("Netzbegrünung Mastowall - gruene.social");
$('.navbar').css('background-color', "#008939");
includeReplies = true;
maxAge = 60 * 60 * 24 * 7;
duration = 10000;
refresh = 30000;
extraCards = [
"<img src='sharepics/Slide1.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide2.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide3.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>",
"<img src='sharepics/Slide4.png' style='max-width: 100%;max-height: 100%;vertical-align: middle;'>"
];
return "https://gruene.social";
}
}
@ -59,16 +100,26 @@ const fetchPosts = async function(serverUrl, hashtag) {
// updateTimesOnPage updates the time information displayed for each post
const updateTimesOnPage = function() {
$('.card-text a').each(function() {
const date = new Date($(this).attr('data-time'));
$('.card-text a.time').each(function() {
const timeValue = $(this).attr('data-time');
if (timeValue === '') return;
const date = new Date(timeValue);
const newTimeAgo = timeAgo(secondsAgo(date));
$(this).text(newTimeAgo);
});
};
// 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
const displayPost = function(post) {
if (existingPosts.includes(post.id) || (!includeReplies && post.in_reply_to_id !== null)) return;
if (existingPosts.includes(post.id) || (!includeReplies && post.in_reply_to_id !== null)) return 0;
existingPosts.push(post.id);
@ -77,12 +128,16 @@ const displayPost = function(post) {
<div class="card m-2 p-2">
<div class="d-flex align-items-center mb-2">
<img src="${post.account.avatar}" class="avatar-img rounded-circle mr-2">
<p class="m-0">${DOMPurify.sanitize(post.account.display_name)}</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>
${post.media_attachments[0] ? `<img src="${post.media_attachments[0].url}" class="card-img-top mb-2">` : ''}
<p class="card-text">${DOMPurify.sanitize(post.content)}</p>
${post.media_attachments[0] ?
(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>` : ''}
<p class="card-text text-right"><small class="text-muted"><a 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>
`;
@ -90,27 +145,149 @@ const displayPost = function(post) {
let $card = $(cardHTML);
$('#wall').prepend($card);
$('.masonry-grid').masonry('prepended', $card);
return 1;
};
const processPosts = function(posts) {
posts = posts.filter((post) => {
return secondsAgo(new Date(post.created_at)) < maxAge && post.content.indexOf("nitter.") === -1 && post.spoiler_text === ""
});
return posts;
};
// updateWall displays all posts
const updateWall = function(posts) {
if (!posts || posts.length === 0) return;
posts = processPosts(posts);
posts.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
posts.forEach(post => displayPost(post));
let ret = 0
posts.forEach(post => ret += displayPost(post));
$('.masonry-grid').masonry('layout');
return ret;
};
// updateCarousel
const updateCarousel = function(slides, posts) {
if (!posts || posts.length === 0) return;
posts = processPosts(posts);
posts.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
// remove slides in carousel
slides.innerHTML = "";
var newHTML = ` <!-- No Indicators -->`
newHTML += `<!-- the slides -->
<div class="carousel-inner">
`;
let existingCards = [];
for( let i = 0; i < posts.length; i++ ) {
let post = posts[i];
if (existingCards.includes(post.id) || (!includeReplies && post.in_reply_to_id !== null)) continue;
existingCards.push(post.id);
/*console.log( post.content )*/
if ( i == 0 ) {
newHTML += `<div class="carousel-item active" data-interval="${duration}" data-pause="false">`;
}
else {
newHTML += `<div class="carousel-item" data-interval="${duration}" data-pause="false">`;
}
const postContent = replaceEmojies(DOMPurify.sanitize(post.content), post.emojis);
newHTML += `
<div class="card-big">
<div class="d-flex align-items-center mb-4">
<img src="${post.account.avatar}" class="avatar-img-big rounded-circle mr-4">
<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>
<hr>
<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 > 700 ? `style="font-size: ${strip(postContent).length > 1000 ? `0.5`:`0.9`}em;"`: ``}>${postContent}</div></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>
<hr>
<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>
${post.favourites_count ? `, <b>${post.favourites_count}</b> mal favorisiert` : '' }
${post.replies_count ? `, <b>${post.replies_count}</b> mal kommentiert` : '' }
${post.reblogs_count ? `, <b>${post.reblogs_count}</b> mal geteilt` : '' }
</small>
</p>
</div>
`;
newHTML += '</div>';
}
for( let i = 0; i < extraCards.length; i++ ) {
newHTML += `<div class="carousel-item" data-interval="${duration * 2}" data-pause="false">
<div className="card-big">
<div class="d-flex align-items-center mb-4">
${extraCards[i]}
</div>
</div>
</div>`;
}
newHTML += '</div>'
document.getElementById("myCarousel").innerHTML = newHTML;
};
const showCarousel = function() {
// show popover
document.getElementById('popover').style.opacity = '1';
document.getElementById('popover').style.display = 'block';
// Activate Carousel
$('#myCarousel').carousel("cycle");
}
const strip = function(html) {
let doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
const hideCarousel = function() {
// hide popover
document.getElementById('popover').style.display = 'none';
// Activate Carousel
}
// hashtagsString returns a single string based on the given array of hashtags
const hashtagsString = function(hashtagsArray) {
return `${hashtagsArray.map(hashtag => `#${hashtag}`).join(' ')}`;
}
// updateHashtagsOnPage updates the displayed hashtags
const updateHashtagsOnPage = function(hashtagsArray) {
$('#hashtag-display').text(hashtagsArray.length > 0 ? `${hashtagsArray.map(hashtag => `#${hashtag}`).join(' ')}` : 'No hashtags set');
$('#hashtag-display').text(hashtagsArray.length > 0 ? hashtagsString(hashtagsArray) : 'No hashtags set');
};
// updateHashtagsOnPage updates the document title by appending the given array of hashtags
const updateHashtagsInTitle = function(hashtagsArray) {
const baseTitle = document.title;
document.title = `${baseTitle} | ${hashtagsString(hashtagsArray)}`;
}
// handleHashtagDisplayClick handles the event when the hashtag display is clicked
const handleHashtagDisplayClick = function(serverUrl) {
$('#app-content').addClass('d-none');
$('#zero-state').removeClass('d-none');
const currentHashtags = getUrlParameter('hashtags').split(',');
if ( currentHashtags = null ) {
currentHasttags = "netzbegruenung,bdk24,wasjetztzählt".split(',')
}
for (let i = 0; i < currentHashtags.length; i++) {
$(`#hashtag${i+1}`).val(currentHashtags[i]);
@ -156,34 +333,61 @@ $(document).ready(async function() {
setInterval(function() {
$('.masonry-grid').masonry('layout');
}, 10000);
const hashtags = getUrlParameter('hashtags');
}, refresh);
let hashtags = getUrlParameter('hashtags');
if ( hashtags == '' ) {
hashtags = "netzbegruenung,bdk24,wasjetztzählt";
}
const hashtagsArray = hashtags ? hashtags.split(',') : [];
const serverUrl = getUrlParameter('server') || defaultServerUrl;
const enableCarousel = getUrlParameter('nbstand' );
if ( enableCarousel == '1' )
withCarousel = true;
console.log("show carousel: "+withCarousel);
$('#hashtag-display').on('click', function() {
handleHashtagDisplayClick(serverUrl);
});
const slides = $('#myCarousel');
const popover = $('#popover');
if (hashtagsArray.length > 0 && hashtagsArray[0] !== '') {
const allPosts = await Promise.all(hashtagsArray.map(hashtag => fetchPosts(serverUrl, hashtag)));
let allPosts = await Promise.all(hashtagsArray.map(hashtag => fetchPosts(serverUrl, hashtag)));
updateWall(allPosts.flat());
setTimeout(function() {
$('.masonry-grid').masonry('layout');
}, 2000);
if ( withCarousel) {
updateCarousel(slides, allPosts.flat());
setTimeout(async function() { showCarousel(); }, duration);
}
else setTimeout(async function() { hideCarousel(); }, duration);
setInterval(async function() {
const newPosts = await Promise.all(hashtagsArray.map(hashtag => fetchPosts(serverUrl, hashtag)));
updateWall(newPosts.flat());
}, 10000);
let updated = updateWall(newPosts.flat());
if ( withCarousel && updated > 0 ) {
updateCarousel(slides, newPosts.flat());
}
}, refresh);
} else {
$('#zero-state').removeClass('d-none');
$('#popover').removeClass('popover');
$('#app-content').addClass('d-none');
}
updateHashtagsOnPage(hashtagsArray);
updateHashtagsInTitle(hashtagsArray);
$('#hashtag-form').on('submit', function(e) {
handleHashtagFormSubmit(e, hashtagsArray);
});
updateTimesOnPage();
setInterval(updateTimesOnPage, 60000);
});

BIN
sharepics/Slide1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
sharepics/Slide2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
sharepics/Slide3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
sharepics/Slide4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -1,8 +1,12 @@
@charset "utf-8";
/* Add some custom CSS for the cards */
.card {
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.2);
background-color: rgb(240,255,240);
}
/* Position the avatar and username in the top left of the card */
@ -46,6 +50,12 @@
margin-bottom: 1px !important;
}
.carousel .card-text {
font-size: 1.6em;
overflow: hidden;
max-height: 50vh;
}
.card {
font-size: 0.9em; /* adjust this value to get the desired text size */
}
@ -62,8 +72,8 @@
/* Custom navbar styles */
.navbar {
height: 50px; /* reduce the height of the navbar */
background-color: rgb(227, 6, 19);
min-height: 50px; /* reduce the height of the navbar */
background-color: rgb(0, 137, 57);
margin-bottom: 10px !important;
top: -10px !important;
padding-top: 14px !important;
@ -72,13 +82,13 @@
.navbar-brand {
color: rgba(255, 255, 255, 0.8) !important; /* change the text color */
margin: 0 auto; /* center the brand name */
font-size: 0.9em;
font-size: 1.8em;
}
.navbar-info {
color: rgba(255, 255, 255, 0.8) !important; /* change the text color */
margin: 0 auto; /* center the brand name */
font-size: 1.2em;
font-size: 2.4em;
display: block !important;
}
@ -124,12 +134,28 @@ body {
height: 50px;
}
.avatar-img-big {
width: 100px;
height: 100px;
}
.avatar-name {
font-size:2em;
font-weight:600;
padding-top:0.3em
}
.user-name {
font-weight: normal;
opacity: 0.7;
}
.container {
max-width: 2000px !important;
}
.footer {
background-color: rgb(200, 200, 200);
background-color: rgb(0, 137, 57);
color: #f2f2f2;
position: fixed;
left: 0;
@ -139,3 +165,66 @@ body {
padding-bottom: 2px !important; /* reduce padding-bottom to half */
font-size: 0.9em;
}
.popover {
position: fixed;
top: 10%;
left: 10%;
width: 80%;
height: 80%;
max-height: 80%;
max-width: 80%;
background-color: rgba(255, 255, 255, .95);
background-clip: padding-box;
border: 0px solid rgba(0, 137, 57, .5);
box-shadow:0 .5rem 1rem rgba(0, 0, 0, .30); !important
border-radius:.8rem;
opacity: 0;
transition: opacity 0.5s linear;
}
.card-big {
font-size: 1.8em;
font-weight: 400;
margin-top: 20px !important;
margin-left: 40px !important;
margin-right: 40px !important;
margin-bottom: 20px !important;
}
.card-img-bottom {
max-width: 600px;
max-height: 500px;
width: auto;
text-align: center;
aspect-ratio: auto !important;
border-top-left-radius: calc(.25rem - 1px);
border-top-right-radius:calc(.25rem - 1px);
margin-top: 0px !important;
margin-bottom: 10px !important;
align-items: center;
float: right;
}
.text-muted {
color:#6c757d !important;
font-size: 1em;
text-align: right;
}
.footer {
font-size: 2em;
}
.footer .text-muted {
color: rgba(255, 255, 255, 0.8) !important;
font-size: 0.8em;
}
.footer a {
color: rgba(255, 255, 255, 0.8) !important;
}
.emoji {
height: 1em;
}