mirror of
https://gitlab.com/idotj/mastodon-embed-timeline.git
synced 2025-05-24 00:42:45 +00:00
v4.0.3
This commit is contained in:
parent
084e66fe5f
commit
cf0cdadff2
@ -1,3 +1,8 @@
|
||||
v4.0.3 - 16/02/2024
|
||||
- Delete duplicated JS/CSS files for examples
|
||||
- Move docker file to root folder and update paths
|
||||
- Add DOMContentLoad for container and body nodes
|
||||
|
||||
v4.0.1 - 08/02/2024
|
||||
- Fix error in emojis present in user/profile title
|
||||
|
||||
|
@ -72,7 +72,7 @@ const myTimeline = new MastodonTimeline();
|
||||
|
||||
By default it will show a timeline with 20 posts from the instance [mastodon.social](https://mastodon.social/public/local)
|
||||
|
||||
ℹ️ If you are trying to use your timeline in a CMS such as Drupal, Wordpress, Joomla, etc... you will need to initialize your script when the whole page has loaded. In that case initialize the script by running:
|
||||
ℹ️ If you are trying to initialize the script before `mastodon-timeline.js` is loaded, you will probably get such an error: "MastodonTimeline is not defined". To fix that initialize the script by running:
|
||||
|
||||
```js
|
||||
window.addEventListener("load", () => {
|
||||
@ -216,7 +216,7 @@ You can pass more options/values to personalize your timeline:
|
||||
|
||||
### Examples
|
||||
|
||||
The folder `examples/` contains several demos in HTML to play with. Just download the folder and open each HTML file in your favorite browser.
|
||||
The folder `examples/` contains several demos in HTML to play with. Download the full project and open each HTML file in your favorite browser.
|
||||
|
||||
Also, you have a Docker file to perform your tests if needed. Simply inside the `examples/` folder run:
|
||||
|
||||
|
2
dist/mastodon-timeline.min.css
vendored
2
dist/mastodon-timeline.min.css
vendored
File diff suppressed because one or more lines are too long
4
dist/mastodon-timeline.min.js
vendored
4
dist/mastodon-timeline.min.js
vendored
File diff suppressed because one or more lines are too long
@ -12,13 +12,13 @@ services:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
volumes:
|
||||
- ./css/mastodon-timeline.css:/var/www/css/mastodon-timeline.css
|
||||
- ./js/mastodon-timeline.js:/var/www/js/mastodon-timeline.js
|
||||
- ./local-timeline.html:/var/www/index.html
|
||||
- ./profile-timeline.html:/var/www/profile-timeline.html
|
||||
- ./hashtag-timeline.html:/var/www/hashtag-timeline.html
|
||||
- ./theme-timeline.html:/var/www/theme-timeline.html
|
||||
- ./multiple-timelines.html:/var/www/multiple-timelines.html
|
||||
- ./src/mastodon-timeline.css:/var/www/src/mastodon-timeline.css
|
||||
- ./src/mastodon-timeline.js:/var/www/src/mastodon-timeline.js
|
||||
- ./examples/local-timeline.html:/var/www/index.html
|
||||
- ./examples/profile-timeline.html:/var/www/profile-timeline.html
|
||||
- ./examples/hashtag-timeline.html:/var/www/hashtag-timeline.html
|
||||
- ./examples/theme-timeline.html:/var/www/theme-timeline.html
|
||||
- ./examples/multiple-timelines.html:/var/www/multiple-timelines.html
|
||||
environment:
|
||||
- PORT=80
|
||||
- SERVER_NAME=mastodon-timeline
|
@ -1,462 +0,0 @@
|
||||
/* Mastodon embed feed timeline v4.0.1 */
|
||||
/* More info at: */
|
||||
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
|
||||
|
||||
/* Variables */
|
||||
.mt-container,
|
||||
.mt-container[data-theme="light"] {
|
||||
--mt-txt-max-lines: none;
|
||||
--mt-color-bg: #fff;
|
||||
--mt-color-bg-hover: #d9e1e8;
|
||||
--mt-color-line-gray: #c0cdd9;
|
||||
--mt-color-contrast-gray: #606984;
|
||||
--mt-color-content-txt: #000;
|
||||
--mt-color-link: #3a3bff;
|
||||
--mt-color-error-txt: #8b0000;
|
||||
--mt-color-btn-bg: #6364ff;
|
||||
--mt-color-btn-bg-hover: #563acc;
|
||||
--mt-color-btn-txt: #fff;
|
||||
}
|
||||
.mt-container[data-theme="dark"] {
|
||||
--mt-color-bg: #282c37;
|
||||
--mt-color-bg-hover: #313543;
|
||||
--mt-color-line-gray: #393f4f;
|
||||
--mt-color-contrast-gray: #606984;
|
||||
--mt-color-content-txt: #fff;
|
||||
--mt-color-link: #8c8dff;
|
||||
--mt-color-error-txt: #fe6c6c;
|
||||
}
|
||||
|
||||
/* Reset CSS */
|
||||
.mt-container button {
|
||||
font: inherit;
|
||||
}
|
||||
.mt-container a,
|
||||
.mt-container button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Main container */
|
||||
.mt-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
background-color: var(--mt-color-bg);
|
||||
scrollbar-color: var(--mt-color-contrast-gray) var(--mt-color-bg);
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
.mt-container::-webkit-scrollbar {
|
||||
width: 0.25rem;
|
||||
height: 0.25rem;
|
||||
}
|
||||
.mt-container::-webkit-scrollbar-thumb {
|
||||
background-color: var(--mt-color-contrast-gray);
|
||||
border: none;
|
||||
border-radius: 3rem;
|
||||
}
|
||||
.mt-container::-webkit-scrollbar-thumb:hover,
|
||||
.mt-container::-webkit-scrollbar-thumb:active {
|
||||
background-color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-container::-webkit-scrollbar-track {
|
||||
background-color: var(--mt-color-bg);
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
.mt-container::-webkit-scrollbar-track:hover,
|
||||
.mt-container::-webkit-scrollbar-track:active,
|
||||
.mt-container::-webkit-scrollbar-corner {
|
||||
background-color: var(--mt-color-bg);
|
||||
}
|
||||
.mt-container a:link,
|
||||
.mt-container a:active,
|
||||
.mt-container a {
|
||||
text-decoration: none;
|
||||
color: var(--mt-color-link);
|
||||
}
|
||||
.mt-container a:not(.mt-post-preview):hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.mt-body {
|
||||
padding: 1rem clamp(0.25rem, 4vw, 1rem);
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-body .invisible {
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* Post container */
|
||||
.mt-post {
|
||||
margin: 0.25rem;
|
||||
padding: 1rem 0.5rem;
|
||||
position: relative;
|
||||
min-height: 3.75rem;
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid var(--mt-color-line-gray);
|
||||
}
|
||||
.mt-post:hover,
|
||||
.mt-post:focus {
|
||||
cursor: pointer;
|
||||
background-color: var(--mt-color-bg-hover);
|
||||
}
|
||||
.mt-post p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* User avatar */
|
||||
.mt-post-avatar {
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
.mt-post-avatar-standard {
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
}
|
||||
.mt-post-avatar-boosted {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
position: relative;
|
||||
}
|
||||
.mt-post-avatar-image-big img {
|
||||
aspect-ratio: 1/1;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.25rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mt-post-avatar-image-small img {
|
||||
aspect-ratio: 1/1;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
top: 1.5rem;
|
||||
left: 1.5rem;
|
||||
position: absolute;
|
||||
border-radius: 0.25rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* User name and date */
|
||||
.mt-post-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-post-header-user {
|
||||
font-weight: 600;
|
||||
margin-top: 0.5rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.mt-post-header-user > a {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
color: var(--mt-color-content-txt) !important;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.mt-post-header-date {
|
||||
font-size: 0.75rem;
|
||||
text-align: right;
|
||||
margin: 0.5rem 0 0 auto;
|
||||
}
|
||||
.mt-post-header-date > a {
|
||||
color: var(--mt-color-contrast-gray) !important;
|
||||
}
|
||||
|
||||
/* Text */
|
||||
.mt-post-txt {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-post-txt .spoiler-txt-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mt-post-txt.truncate {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: var(--mt-txt-max-lines);
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.mt-post-txt:not(.truncate) .ellipsis::after {
|
||||
content: "...";
|
||||
}
|
||||
.mt-post-txt blockquote {
|
||||
border-left: 0.25rem solid var(--mt-color-line-gray);
|
||||
margin-left: 0;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
.mt-post-header-user .mt-custom-emoji,
|
||||
.mt-post-txt .mt-custom-emoji {
|
||||
height: 1.5rem;
|
||||
min-width: 1.5rem;
|
||||
margin-bottom: -0.25rem;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Poll */
|
||||
.mt-post-poll {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-post-poll ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.mt-post-poll ul li {
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.mt-post-poll.mt-post-poll-expired ul li {
|
||||
color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-post-poll ul li:not(:last-child) {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.mt-post-poll ul li:before {
|
||||
content: "◯";
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.mt-post-poll.mt-post-poll-expired ul li:before {
|
||||
content: "";
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Medias */
|
||||
.mt-post-media {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-post-media-spoiler > img,
|
||||
.mt-post-media-spoiler > audio,
|
||||
.mt-post-media-spoiler > video,
|
||||
.mt-post-media-spoiler > .mt-post-media-play-icon {
|
||||
filter: blur(2rem);
|
||||
pointer-events: none;
|
||||
}
|
||||
.mt-post-media > audio {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.mt-post-media > img,
|
||||
.mt-post-media > video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-post-media.mt-loading-spinner .mt-post-media-play-icon {
|
||||
display: none;
|
||||
}
|
||||
.mt-post-media-play-icon {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
top: calc(50% - 1.5rem);
|
||||
left: calc(50% - 1.5rem);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mt-post-media-play-icon > svg {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
fill: var(--mt-color-bg);
|
||||
stroke: var(--mt-color-content-txt);
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
/* Preview link */
|
||||
.mt-post-preview {
|
||||
min-height: 4rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid var(--mt-color-line-gray);
|
||||
border-radius: 0.5rem;
|
||||
color: var(--mt-color-link);
|
||||
font-size: 0.8rem;
|
||||
margin: 1rem 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mt-post-preview-image {
|
||||
width: 40%;
|
||||
align-self: stretch;
|
||||
}
|
||||
.mt-post-preview-image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-post-preview-noImage {
|
||||
width: 40%;
|
||||
font-size: 1.5rem;
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
}
|
||||
.mt-post-preview-content {
|
||||
width: 60%;
|
||||
display: flex;
|
||||
align-self: center;
|
||||
flex-direction: column;
|
||||
padding: 0.5rem 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.mt-post-preview-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Counter bar */
|
||||
.mt-post-counter-bar {
|
||||
display: flex;
|
||||
min-width: 6rem;
|
||||
max-width: 40rem;
|
||||
justify-content: space-between;
|
||||
color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-post-counter-bar-replies,
|
||||
.mt-post-counter-bar-reblog,
|
||||
.mt-post-counter-bar-favorites {
|
||||
display: flex;
|
||||
font-size: 0.75rem;
|
||||
gap: 0.25rem;
|
||||
align-items: center;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.mt-post-counter-bar-replies > svg,
|
||||
.mt-post-counter-bar-reblog > svg,
|
||||
.mt-post-counter-bar-favorites > svg {
|
||||
width: 1rem;
|
||||
fill: var(--mt-color-contrast-gray);
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.mt-container .mt-btn-dark {
|
||||
display: flex;
|
||||
border-radius: 0.25rem;
|
||||
background-color: var(--mt-color-line-gray);
|
||||
border: 0;
|
||||
color: var(--mt-color-content-txt);
|
||||
font-weight: 600;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
padding: 0 0.5rem;
|
||||
line-height: 1.25rem;
|
||||
|
||||
vertical-align: top;
|
||||
}
|
||||
.mt-container .mt-btn-violet,
|
||||
.mt-container a.mt-btn-violet {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
border: 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
background-color: var(--mt-color-btn-bg);
|
||||
color: var(--mt-color-btn-txt);
|
||||
}
|
||||
.mt-container .mt-btn-violet:hover,
|
||||
.mt-container a.mt-btn-violet:hover {
|
||||
background-color: var(--mt-color-btn-bg-hover);
|
||||
text-decoration: none;
|
||||
}
|
||||
.mt-post-txt .mt-btn-spoiler {
|
||||
display: inline-block;
|
||||
}
|
||||
.mt-post-media.mt-loading-spinner > .mt-btn-spoiler {
|
||||
display: none;
|
||||
}
|
||||
.mt-post-media > .mt-btn-spoiler {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 2;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.mt-error {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - 3.5rem);
|
||||
width: calc(100% - 4.5rem);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--mt-color-error-txt);
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
}
|
||||
.mt-error-icon {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.mt-error-message {
|
||||
width: 100%;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.mt-error-message hr {
|
||||
color: var(--mt-color-line-gray);
|
||||
}
|
||||
|
||||
/* Loading spinner */
|
||||
.mt-body > .mt-loading-spinner {
|
||||
position: absolute;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin: auto;
|
||||
top: calc(50% - 1.5rem);
|
||||
right: calc(50% - 1.5rem);
|
||||
}
|
||||
.mt-loading-spinner {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 128 128'%3E%3Cg%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 64 64' to='360 64 64' dur='1000ms' repeatCount='indefinite'/%3E%3Cpath d='M64 6.69a57.3 57.3 0 1 1 0 114.61A57.3 57.3 0 0 1 6.69 64' fill='none' stroke='%23404040' stroke-width='12'/%3E%3C/g%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-color: transparent;
|
||||
background-size: min(2.5rem, calc(100% - 0.5rem));
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.mt-footer {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
margin: auto auto 2rem auto;
|
||||
padding: 0 1.5rem;
|
||||
gap: 1.5rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Hidden elements */
|
||||
.visually-hidden {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
padding: 0 !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
border: 0 !important;
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./css/mastodon-timeline.css" />
|
||||
<link rel="stylesheet" href="../src/mastodon-timeline.css" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -103,7 +103,7 @@
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script src="../src/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./css/mastodon-timeline.css" />
|
||||
<link rel="stylesheet" href="../src/mastodon-timeline.css" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -130,7 +130,7 @@
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script src="../src/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline();
|
||||
</script>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./css/mastodon-timeline.css" />
|
||||
<link rel="stylesheet" href="../src/mastodon-timeline.css" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -96,17 +96,17 @@
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
const myTimeline01 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
instanceUrl: "https://mastodon.social",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
const myTimeline02 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
instanceUrl: "https://mastodon.online",
|
||||
});
|
||||
|
||||
const myTimeline3 = new MastodonTimeline({
|
||||
const myTimeline03 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-03",
|
||||
instanceUrl: "https://mstdn.social",
|
||||
});
|
||||
@ -144,19 +144,19 @@
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script src="../src/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
const myTimeline01 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
instanceUrl: "https://mastodon.social",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
const myTimeline02 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
instanceUrl: "https://mastodon.online",
|
||||
});
|
||||
|
||||
const myTimeline3 = new MastodonTimeline({
|
||||
const myTimeline03 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-03",
|
||||
instanceUrl: "https://mstdn.social",
|
||||
});
|
||||
|
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./css/mastodon-timeline.css" />
|
||||
<link rel="stylesheet" href="../src/mastodon-timeline.css" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -104,7 +104,7 @@
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script src="../src/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
|
@ -8,7 +8,7 @@
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./css/mastodon-timeline.css" />
|
||||
<link rel="stylesheet" href="../src/mastodon-timeline.css" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
@ -95,7 +95,7 @@
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
const myTimeline01 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
defaultTheme: "light",
|
||||
});
|
||||
@ -111,7 +111,7 @@
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
const myTimeline02 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
defaultTheme: "dark",
|
||||
});
|
||||
@ -126,20 +126,20 @@
|
||||
You can change your timeline color calling the function <strong>mtColorTheme()</strong>
|
||||
</p>
|
||||
<div class="dummy-buttons-container">
|
||||
<button onclick="myTimeline1.mtColorTheme('dark')">
|
||||
<button onclick="myTimeline01.mtColorTheme('dark')">
|
||||
Switch 1st timeline to dark theme
|
||||
</button>
|
||||
<button onclick="myTimeline2.mtColorTheme('light')">
|
||||
<button onclick="myTimeline02.mtColorTheme('light')">
|
||||
Switch 2nd timeline to light theme
|
||||
</button>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
<button onclick="myTimeline1.mtColorTheme('dark')">
|
||||
<button onclick="myTimeline01.mtColorTheme('dark')">
|
||||
Switch 1st timeline to dark theme
|
||||
</button>
|
||||
|
||||
<button onclick="myTimeline2.mtColorTheme('light')">
|
||||
<button onclick="myTimeline02.mtColorTheme('light')">
|
||||
Switch 2nd timeline to light theme
|
||||
</button>
|
||||
</code>
|
||||
@ -166,14 +166,14 @@
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script src="../src/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
const myTimeline01 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
defaultTheme: "light",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
const myTimeline02 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
defaultTheme: "dark",
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "@idotj/mastodon-embed-feed-timeline",
|
||||
"description": "Displays Mastodon timeline with posts embed in your website. Very easy to setup, no dependencies, no trackers, cross-browser, WCAG compliant and fully responsive.",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.3",
|
||||
"private": false,
|
||||
"author": {
|
||||
"name": "idotj"
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Mastodon embed feed timeline v4.0.1 */
|
||||
/* Mastodon embed feed timeline v4.0.3 */
|
||||
/* More info at: */
|
||||
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Mastodon embed feed timeline
|
||||
* @author idotj
|
||||
* @version 4.0.1
|
||||
* @version 4.0.3
|
||||
* @url https://gitlab.com/idotj/mastodon-embed-feed-timeline
|
||||
* @license GNU AGPLv3
|
||||
*/
|
||||
@ -11,7 +11,6 @@ class MastodonTimeline {
|
||||
constructor(customSettings = {}) {
|
||||
this.defaultSettings = {
|
||||
mtContainerId: "mt-container",
|
||||
mtBody: "",
|
||||
instanceUrl: "https://mastodon.social",
|
||||
timelineType: "local",
|
||||
userId: "",
|
||||
@ -35,38 +34,70 @@ class MastodonTimeline {
|
||||
btnShowContent: "SHOW CONTENT",
|
||||
btnSeeMore: "See more posts at Mastodon",
|
||||
btnReload: "Refresh",
|
||||
fetchedData: {},
|
||||
};
|
||||
|
||||
this.mtSettings = { ...this.defaultSettings, ...customSettings };
|
||||
|
||||
// Set node of body container
|
||||
this.mtSettings.mtBody = document
|
||||
.getElementById(this.mtSettings.mtContainerId)
|
||||
.getElementsByClassName("mt-body")[0];
|
||||
this.mtContainerNode = "";
|
||||
this.mtBodyNode = "";
|
||||
this.fetchedData = {};
|
||||
|
||||
this.mtInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger callback when DOM loaded or complete
|
||||
* @param {function} c Callback executed
|
||||
*/
|
||||
onDOMContentLoaded(c) {
|
||||
if (
|
||||
typeof document !== "undefined" &&
|
||||
(document.readyState === "complete" ||
|
||||
document.readyState === "interactive")
|
||||
) {
|
||||
c();
|
||||
} else if (
|
||||
typeof document !== "undefined" &&
|
||||
(document.readyState !== "complete" ||
|
||||
document.readyState !== "interactive")
|
||||
) {
|
||||
document.addEventListener("DOMContentLoaded", c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and build the timeline
|
||||
*/
|
||||
mtInit() {
|
||||
// console.log("Init Mastodon timeline. Settings: ", this.mtSettings);
|
||||
this.#loadColorTheme();
|
||||
this.#buildTimeline("newTimeline");
|
||||
// console.log("Creating Mastodon timeline with settings: ", this.mtSettings);
|
||||
|
||||
this.onDOMContentLoaded(() => {
|
||||
// Register container node
|
||||
this.mtContainerNode = document.getElementById(
|
||||
this.mtSettings.mtContainerId
|
||||
);
|
||||
|
||||
// Register body node
|
||||
this.mtBodyNode =
|
||||
this.mtContainerNode.getElementsByClassName("mt-body")[0];
|
||||
|
||||
this.#loadColorTheme();
|
||||
this.#buildTimeline("newTimeline");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the timeline by fetching the lastest posts
|
||||
*/
|
||||
mtUpdate() {
|
||||
this.mtSettings.mtBody.replaceChildren();
|
||||
this.mtSettings.mtBody.insertAdjacentHTML(
|
||||
"afterbegin",
|
||||
'<div class="mt-loading-spinner"></div>'
|
||||
);
|
||||
this.#buildTimeline("updateTimeline");
|
||||
this.onDOMContentLoaded(() => {
|
||||
this.mtBodyNode.replaceChildren();
|
||||
this.mtBodyNode.insertAdjacentHTML(
|
||||
"afterbegin",
|
||||
'<div class="mt-loading-spinner"></div>'
|
||||
);
|
||||
this.#buildTimeline("updateTimeline");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,9 +105,9 @@ class MastodonTimeline {
|
||||
* @param {string} themeType Type of color theme
|
||||
*/
|
||||
mtColorTheme(themeType) {
|
||||
document
|
||||
.getElementById(this.mtSettings.mtContainerId)
|
||||
.setAttribute("data-theme", themeType);
|
||||
this.onDOMContentLoaded(() => {
|
||||
this.mtContainerNode.setAttribute("data-theme", themeType);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,7 +231,7 @@ class MastodonTimeline {
|
||||
await this.#fetchTimelineData();
|
||||
|
||||
// Empty container body
|
||||
this.mtSettings.mtBody.replaceChildren();
|
||||
this.mtBodyNode.replaceChildren();
|
||||
|
||||
// Set posts counter to 0
|
||||
let nbPostShow = 0;
|
||||
@ -235,7 +266,7 @@ class MastodonTimeline {
|
||||
}
|
||||
|
||||
// If there are no posts to display, show an error message
|
||||
if (this.mtSettings.mtBody.innerHTML === "") {
|
||||
if (this.mtBodyNode.innerHTML === "") {
|
||||
const errorMessage =
|
||||
"No posts to show <hr/>" +
|
||||
(this.mtSettings.fetchedData.timeline?.length || 0) +
|
||||
@ -260,10 +291,7 @@ class MastodonTimeline {
|
||||
* @param {number} i Index of post
|
||||
*/
|
||||
#appendPost(c, i) {
|
||||
this.mtSettings.mtBody.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
this.#assamblePost(c, i)
|
||||
);
|
||||
this.mtBodyNode.insertAdjacentHTML("beforeend", this.#assamblePost(c, i));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -406,7 +434,7 @@ class MastodonTimeline {
|
||||
let txtCss = "";
|
||||
if (this.mtSettings.txtMaxLines !== "0") {
|
||||
txtCss = " truncate";
|
||||
this.mtSettings.mtBody.parentNode.style.setProperty(
|
||||
this.mtBodyNode.parentNode.style.setProperty(
|
||||
"--mt-txt-max-lines",
|
||||
this.mtSettings.txtMaxLines
|
||||
);
|
||||
@ -862,7 +890,7 @@ class MastodonTimeline {
|
||||
* @param {object} c Preview link content
|
||||
* @returns {string} Preview link in HTML format
|
||||
*/
|
||||
#createPreviewLink = function (c) {
|
||||
#createPreviewLink(c) {
|
||||
const card =
|
||||
'<a href="' +
|
||||
c.url +
|
||||
@ -895,7 +923,7 @@ class MastodonTimeline {
|
||||
"</a>";
|
||||
|
||||
return card;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse HTML string
|
||||
@ -914,14 +942,13 @@ class MastodonTimeline {
|
||||
#buildFooter() {
|
||||
if (this.mtSettings.btnSeeMore || this.mtSettings.btnReload) {
|
||||
// Add footer container
|
||||
this.mtSettings.mtBody.parentNode.insertAdjacentHTML(
|
||||
this.mtBodyNode.parentNode.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
'<div class="mt-footer"></div>'
|
||||
);
|
||||
|
||||
const containerFooter = document
|
||||
.getElementById(this.mtSettings.mtContainerId)
|
||||
.getElementsByClassName("mt-footer")[0];
|
||||
const containerFooter =
|
||||
this.mtContainerNode.getElementsByClassName("mt-footer")[0];
|
||||
|
||||
// Create button to open Mastodon page
|
||||
if (this.mtSettings.btnSeeMore) {
|
||||
@ -962,9 +989,8 @@ class MastodonTimeline {
|
||||
|
||||
containerFooter.insertAdjacentHTML("beforeend", btnReloadHTML);
|
||||
|
||||
const reloadBtn = document
|
||||
.getElementById(this.mtSettings.mtContainerId)
|
||||
.getElementsByClassName("btn-refresh")[0];
|
||||
const reloadBtn =
|
||||
this.mtContainerNode.getElementsByClassName("btn-refresh")[0];
|
||||
reloadBtn.addEventListener("click", () => {
|
||||
this.mtUpdate();
|
||||
});
|
||||
@ -976,7 +1002,7 @@ class MastodonTimeline {
|
||||
* Add EventListeners for timeline interactions and trigger functions
|
||||
*/
|
||||
#setPostsInteracion() {
|
||||
this.mtSettings.mtBody.addEventListener("click", (e) => {
|
||||
this.mtBodyNode.addEventListener("click", (e) => {
|
||||
// Check if post cointainer was clicked
|
||||
if (
|
||||
e.target.localName == "article" ||
|
||||
@ -1007,7 +1033,7 @@ class MastodonTimeline {
|
||||
this.#loadPostVideo(e);
|
||||
}
|
||||
});
|
||||
this.mtSettings.mtBody.addEventListener("keydown", (e) => {
|
||||
this.mtBodyNode.addEventListener("keydown", (e) => {
|
||||
// Check if Enter key was pressed with focus in an article
|
||||
if (e.key === "Enter" && e.target.localName == "article") {
|
||||
this.#openPostUrl(e);
|
||||
@ -1048,7 +1074,7 @@ class MastodonTimeline {
|
||||
e.target.removeEventListener("error", removeSpinner);
|
||||
};
|
||||
// Add EventListener to images
|
||||
this.mtSettings.mtBody
|
||||
this.mtBodyNode
|
||||
.querySelectorAll(`.${this.mtSettings.spinnerClass} > img`)
|
||||
.forEach((e) => {
|
||||
e.addEventListener("load", removeSpinner);
|
||||
@ -1063,13 +1089,13 @@ class MastodonTimeline {
|
||||
*/
|
||||
#showError(t, i) {
|
||||
const icon = i || "❌";
|
||||
this.mtSettings.mtBody.innerHTML =
|
||||
this.mtBodyNode.innerHTML =
|
||||
'<div class="mt-error"><span class="mt-error-icon">' +
|
||||
icon +
|
||||
'</span><br/><strong>Oops, something\'s happened:</strong><br/><div class="mt-error-message">' +
|
||||
t +
|
||||
"</div></div>";
|
||||
this.mtSettings.mtBody.setAttribute("role", "none");
|
||||
this.mtBodyNode.setAttribute("role", "none");
|
||||
throw new Error(
|
||||
"Stopping the script due to an error building the timeline."
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user