mirror of
https://gitlab.com/idotj/mastodon-embed-timeline.git
synced 2025-05-23 16:32:47 +00:00
Release v4
This commit is contained in:
parent
182d3aeb9b
commit
3dc175a64e
@ -1,3 +1,4 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
@ -9,6 +10,7 @@ indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[**.min.js]
|
||||
|
141
.gitignore
vendored
141
.gitignore
vendored
@ -1,4 +1,143 @@
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/linux
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
### Node Patch ###
|
||||
# Serverless Webpack directories
|
||||
.webpack/
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
# SvelteKit build / generate output
|
||||
.svelte-kit
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
|
15
CHANGELOG
15
CHANGELOG
@ -1,3 +1,16 @@
|
||||
v4.0.0 - xx/02/2024
|
||||
- Revamped JS (ES6)
|
||||
- Renamed CSS classes
|
||||
- Improved performance
|
||||
- Removed the use of the word "toot" in code and comments
|
||||
- Dynamic text for content-sensitive "Show/Hide" buttons
|
||||
- Easier way to customize timeline settings
|
||||
- Button to refresh timeline
|
||||
- Improved theme color management
|
||||
- Improve error messages
|
||||
- Possibility to have several timelines on the same page
|
||||
- Fixed inconsistency in video aspect ratio
|
||||
|
||||
v3.13.3 - 16/01/2024
|
||||
- Add Docker compose
|
||||
|
||||
@ -49,7 +62,7 @@ v3.9.0 - 02/09/2023
|
||||
|
||||
v3.8.2 - 26/08/2023
|
||||
- Add support to customized emojis
|
||||
- Javascript refactoring to allow multiple requests
|
||||
- JavaScript refactoring to allow multiple requests
|
||||
|
||||
v3.8.1 - 14/08/2023
|
||||
- Show preview card from link, photo or video URL
|
||||
|
264
README.md
264
README.md
@ -1,4 +1,4 @@
|
||||
# 🐘 Mastodon embed timeline
|
||||
# 🐘 Mastodon embed timeline (new v4)
|
||||
|
||||

|
||||
|
||||
@ -7,108 +7,233 @@ Embed a mastodon feed timeline in your page, only with a CSS and JS file.
|
||||
Demo running:
|
||||
<https://codepen.io/ipuntoj/pen/MWppNGL>
|
||||
|
||||
## 🗂️ User guide
|
||||
## 📋 Table of contents
|
||||
|
||||
### Install
|
||||
- [**Installation**](#installation)
|
||||
- [**Usage**](#usage)
|
||||
- [Initialize](#initialize)
|
||||
- [Local timeline](#local-timeline)
|
||||
- [Profile timeline](#profile-timeline)
|
||||
- [Hashtag timeline](#hashtag-timeline)
|
||||
- [Customize](#customize)
|
||||
- [API](#api)
|
||||
- [Examples](#examples)
|
||||
- [Browser support](#browser-support)
|
||||
|
||||
Just copy both files (_mastodon-timeline.css_ and _mastodon-timeline.js_ from /src folder) in your project folder.
|
||||
## Installation
|
||||
|
||||
Now call each one in your page using the `<link>` and `<script>` tag:
|
||||
Ready-to-use compiled and minified files to easily start.
|
||||
|
||||
- Download into your project the following files:
|
||||
- `dist/mastodon-timeline.min.css`
|
||||
- `dist/mastodon-timeline.min.js`
|
||||
|
||||
Now call the CSS and JS files in your HTML page using the `<link>` and `<script>` tags as follows in this example:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="mastodon-timeline.css" />
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
|
||||
<!-- CSS -->
|
||||
<link href="path/to/mastodon-timeline.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<!-- Your HTML content -->
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="path/to/mastodon-timeline.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```html
|
||||
<script src="mastodon-timeline.js"></script>
|
||||
```
|
||||
## Usage
|
||||
|
||||
Then copy the following html structure:
|
||||
### Initialize
|
||||
|
||||
The first step to get your timeline up is to add the following HTML structure in your page:
|
||||
|
||||
```html
|
||||
<div class="mt-container">
|
||||
<div id="mt-body" class="mt-body" role="feed">
|
||||
<div class="loading-spinner"></div>
|
||||
<div id="mt-container" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Great, you have a Mastodon timeline running in your page.
|
||||
Then after that you can initialize the script by running:
|
||||
|
||||
### Setup
|
||||
|
||||
Edit the the JS file _mastodon-timeline.js_ and at the beginning find these two lines:
|
||||
|
||||
```javascript
|
||||
instance_url: 'Your Mastodon instance (not including the last `/` symbol)',
|
||||
timeline_type: 'local',
|
||||
```js
|
||||
const myTimeline = new MastodonTimeline();
|
||||
```
|
||||
|
||||
Enter your Mastodon instance URL and reload the page. You should see toots from your local instance in your timeline.
|
||||
By default it will show a timeline with 20 posts from the instance [mastodon.social](https://mastodon.social/public/local)
|
||||
|
||||
If you want to show a profile timeline then change the `timeline_type` to `profile` and set the following values:
|
||||
ℹ️ 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:
|
||||
|
||||
```javascript
|
||||
user_id: 'Your user ID number on Mastodon instance',
|
||||
profile_name: 'Your user name on Mastodon instance (including the `@` symbol at the beginning)',
|
||||
```js
|
||||
window.addEventListener("load", () => {
|
||||
const myTimeline = new MastodonTimeline();
|
||||
});
|
||||
```
|
||||
|
||||
If you prefer to show a timeline with a specific hashtag then change the `timeline_type` to `hashtag` and enter the name of the hashtag:
|
||||
#### Local timeline
|
||||
|
||||
```javascript
|
||||
hashtag_name: 'YourHashtag (not including the `#` symbol)',
|
||||
Add the following option/value when initializing the timeline:
|
||||
|
||||
```js
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
});
|
||||
```
|
||||
|
||||
Also you have some parameters to customize your embed timeline:
|
||||
It will show a timeline with posts from the instance [mastodon.online](https://mastodon.online/public/local)
|
||||
|
||||
```javascript
|
||||
// Preferred color theme: 'light', 'dark' or 'auto'. Default: auto
|
||||
default_theme: "auto",
|
||||
#### Profile timeline
|
||||
|
||||
// Maximum amount of toots to get. Default: 20
|
||||
toots_limit: "20",
|
||||
Add the following options/values when initializing the timeline:
|
||||
|
||||
// Hide unlisted toots. Default: don't hide
|
||||
hide_unlisted: false,
|
||||
|
||||
// Hide boosted toots. Default: don't hide
|
||||
hide_reblog: false,
|
||||
|
||||
// Hide replies toots. Default: don't hide
|
||||
hide_replies: false,
|
||||
|
||||
// Hide video image preview and load video player instead. Default: don't hide
|
||||
hide_video_preview: false,
|
||||
|
||||
// Hide preview for links. Default: don't hide
|
||||
hide_preview_link: false,
|
||||
|
||||
// Hide custom emojis available on the server. Default: don't hide
|
||||
hide_emojos: false,
|
||||
|
||||
// Converts Markdown symbol ">" at the beginning of a paragraph into a blockquote HTML tag. Default: don't apply
|
||||
markdown_blockquote: false,
|
||||
|
||||
// Limit the text content to a maximum number of lines. Default: 0 (unlimited)
|
||||
text_max_lines: "0",
|
||||
|
||||
// Hide replies, boosts and favourites toots counter. Default: don't hide
|
||||
hide_counter_bar: false,
|
||||
|
||||
// Customize the text of the link pointing to the Mastodon page (appears after the last toot)
|
||||
link_see_more: "See more posts at Mastodon",
|
||||
```js
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "profile",
|
||||
userId: "000180745",
|
||||
profileName: "@idotj",
|
||||
});
|
||||
```
|
||||
|
||||
### Tip
|
||||
It will show a timeline with posts from my Mastodon profile [@idotj](https://mastodon.online/@idotj)
|
||||
|
||||
To setup a **profile timeline** you will need your `user_id` number. If you don't know it you have two ways to get it:
|
||||
ℹ️ If you don't know your `userId` you have two ways to get it:
|
||||
|
||||
- Copy the url below and paste it in a new tab. Remember to replace the words `INSTANCE` and `USERNAME` with your current values in the url:
|
||||
<https://INSTANCE/api/v1/accounts/lookup?acct=USERNAME>
|
||||
The first value you see in the list is your `id` number.
|
||||
|
||||
- Click on the link below and put your `@USERNAME` and `@INSTANCE` in the input field:
|
||||
<a href="https://prouser123.me/mastodon-userid-lookup/" target="_blank" rel="noopener">https://prouser123.me/mastodon-userid-lookup/</a>
|
||||
[https://prouser123.me/mastodon-userid-lookup/](https://prouser123.me/mastodon-userid-lookup/)
|
||||
|
||||
#### Hashtag timeline
|
||||
|
||||
Add the following options/values when initializing the timeline:
|
||||
|
||||
```js
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "hashtag",
|
||||
hashtagName: "fediverse",
|
||||
});
|
||||
```
|
||||
|
||||
It will show a timeline with posts containing the hashtag [#fediverse](https://mastodon.online/tags/fediverse)
|
||||
|
||||
### Customize
|
||||
|
||||
You can pass more options/values to personalize your timeline:
|
||||
|
||||
```js
|
||||
// Id of the <div> containing the timeline
|
||||
mtContainerId: "mt-container",
|
||||
|
||||
// Mastodon instance Url (including https://)
|
||||
instanceUrl: "https://mastodon.social",
|
||||
|
||||
// Choose type of posts to show in the timeline: 'local', 'profile', 'hashtag'. Default: local
|
||||
timelineType: "local",
|
||||
|
||||
// Your user ID number on Mastodon instance. Leave it empty if you didn't choose 'profile' as type of timeline
|
||||
userId: "",
|
||||
|
||||
// Your user name on Mastodon instance (including the @ symbol at the beginning). Leave it empty if you didn't choose 'profile' as type of timeline
|
||||
profileName: "",
|
||||
|
||||
// The name of the hashtag (not including the # symbol). Leave it empty if you didn't choose 'hashtag' as type of timeline
|
||||
hashtagName: "",
|
||||
|
||||
// Class name for the loading spinner (also used in CSS file)
|
||||
spinnerClass: "mt-loading-spinner",
|
||||
|
||||
// Preferred color theme: 'light', 'dark' or 'auto'. Default: auto
|
||||
defaultTheme: "auto",
|
||||
|
||||
// Maximum number of posts to request to the server. Default: 20
|
||||
maxNbPostFetch: "20",
|
||||
|
||||
// Maximum number of posts to show in the timeline. Default: 20
|
||||
maxNbPostShow: "20",
|
||||
|
||||
// Hide unlisted posts. Default: don't hide
|
||||
hideUnlisted: false,
|
||||
|
||||
// Hide boosted posts. Default: don't hide
|
||||
hideReblog: false,
|
||||
|
||||
// Hide replies posts. Default: don't hide
|
||||
hideReplies: false,
|
||||
|
||||
// Hide video image preview and load video player instead. Default: don't hide
|
||||
hideVideoPreview: false,
|
||||
|
||||
// Hide preview card if post contains a link, photo or video from a Url. Default: don't hide
|
||||
hidePreviewLink: false,
|
||||
|
||||
// Hide custom emojis available on the server. Default: don't hide
|
||||
hideEmojos: false,
|
||||
|
||||
// Converts Markdown symbol ">" at the beginning of a paragraph into a blockquote HTML tag. Default: don't apply
|
||||
markdownBlockquote: false,
|
||||
|
||||
// Hide replies, boosts and favourites posts counter. Default: don't hide
|
||||
hideCounterBar: false,
|
||||
|
||||
// Limit the text content to a maximum number of lines. Default: 0 (unlimited)
|
||||
txtMaxLines: "0",
|
||||
|
||||
// Customize the text of the button used for showing/hiding sensitive/spolier text
|
||||
btnShowMore: "SHOW MORE",
|
||||
btnShowLess: "SHOW LESS",
|
||||
|
||||
// Customize the text of the button used for showing sensitive/spolier media content
|
||||
btnShowContent: "SHOW CONTENT",
|
||||
|
||||
// Customize the text of the button pointing to the Mastodon page placed at the end of the timeline. Leave the value empty to hide it
|
||||
btnSeeMore: "See more posts at Mastodon",
|
||||
|
||||
// Customize the text of the button reloading the list of posts placed at the end of the timeline. Leave the value empty to hide it
|
||||
btnReload: "Refresh",
|
||||
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
| Function | Description |
|
||||
| --- | --- |
|
||||
| `mtColorTheme(themeType)` | Apply a theme color. `themeType` accepts only two values: `light` or `dark` |
|
||||
| `mtUpdate()` | Reload the timeline by fetching the lastest posts |
|
||||
|
||||
### 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.
|
||||
|
||||
Also, you have a Docker file to perform your tests if needed. Simply inside the `/examples` folder run:
|
||||
|
||||
```terminal
|
||||
docker compose up
|
||||
```
|
||||
|
||||
### Browser support
|
||||
|
||||
Mastodon embed timeline is supported on the latest versions of the following browsers:
|
||||
|
||||
- Chrome
|
||||
- Firefox
|
||||
- Edge
|
||||
- Safari
|
||||
- Brave
|
||||
- Opera
|
||||
|
||||
## 🚀 Improve me
|
||||
|
||||
@ -120,5 +245,8 @@ GNU Affero General Public License v3.0
|
||||
|
||||
## 💬 FAQ
|
||||
|
||||
Check the [closed issues](https://gitlab.com/idotj/mastodon-embed-feed-timeline/-/issues/?sort=created_date&state=closed&first_page_size=20), you might find your question there.
|
||||
Check the [closed issues](https://gitlab.com/idotj/mastodon-embed-feed-timeline/-/issues/?sort=created_date&state=closed&first_page_size=20), you might find your question there.
|
||||
|
||||
If nothing matches with your problem, check the [open issues](https://gitlab.com/idotj/mastodon-embed-feed-timeline/-/issues/?sort=created_date&state=opened&first_page_size=20) or feel free to create a new one.
|
||||
|
||||
Looking for a previous version of Mastodon embed timeline? Check on the tags list to see all the released versions: [Tags version history](https://gitlab.com/idotj/mastodon-embed-feed-timeline/-/tags)
|
||||
|
1
dist/mastodon-timeline.min.css
vendored
Normal file
1
dist/mastodon-timeline.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
dist/mastodon-timeline.min.js
vendored
Normal file
7
dist/mastodon-timeline.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
462
examples/css/mastodon-timeline.css
Normal file
462
examples/css/mastodon-timeline.css
Normal file
@ -0,0 +1,462 @@
|
||||
/* Mastodon embed feed timeline v4.0.0 */
|
||||
/* 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;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# $ docker compose up
|
||||
|
||||
version: '3.3'
|
||||
version: "3.3"
|
||||
|
||||
services:
|
||||
lighttpd:
|
||||
@ -12,9 +12,13 @@ services:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
volumes:
|
||||
- ./src/index.html:/var/www/index.html
|
||||
- ./src/mastodon-timeline.js:/var/www/mastodon-timeline.js
|
||||
- ./src/mastodon-timeline.css:/var/www/mastodon-timeline.css
|
||||
- ./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
|
||||
environment:
|
||||
- PORT=80
|
||||
- SERVER_NAME=mastodon-timeline
|
115
examples/hashtag-timeline.html
Normal file
115
examples/hashtag-timeline.html
Normal file
@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<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" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background: lightgrey;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-main-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.dummy-wrapper-text,
|
||||
.dummy-wrapper-timeline {
|
||||
width: 50%;
|
||||
max-width: 30rem;
|
||||
height: calc(100% - 4rem);
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.dummy-wrapper-text h1,
|
||||
.dummy-wrapper-text h2,
|
||||
.dummy-wrapper-text p {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
.dummy-wrapper-text pre {
|
||||
display: flex;
|
||||
background: lightsteelblue;
|
||||
border-left: 3px solid #563acc;
|
||||
color: midnightblue;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.dummy-wrapper-text hr {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-main-container">
|
||||
<!-- Title + Explained details of the example -->
|
||||
<div class="dummy-wrapper-text">
|
||||
<h1>🐘 Mastodon embed timeline</h1>
|
||||
<h2>Profile timeline</h2>
|
||||
<p>
|
||||
This example shows posts containing the hashtag
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.online/tags/fediverse"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>#fediverse</a
|
||||
>
|
||||
</p>
|
||||
<p>It has been initialized with the following script:</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "hashtag",
|
||||
hashtagName: "fediverse",
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline -->
|
||||
<div id="mt-container" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "hashtag",
|
||||
hashtagName: "fediverse",
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1069
examples/js/mastodon-timeline.js
Normal file
1069
examples/js/mastodon-timeline.js
Normal file
File diff suppressed because it is too large
Load Diff
138
examples/local-timeline.html
Normal file
138
examples/local-timeline.html
Normal file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<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" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background: lightgrey;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-main-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.dummy-wrapper-text,
|
||||
.dummy-wrapper-timeline {
|
||||
width: 50%;
|
||||
max-width: 30rem;
|
||||
height: calc(100% - 4rem);
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.dummy-wrapper-text h1,
|
||||
.dummy-wrapper-text h2,
|
||||
.dummy-wrapper-text p {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
.dummy-wrapper-text pre {
|
||||
display: flex;
|
||||
background: lightsteelblue;
|
||||
border-left: 3px solid #563acc;
|
||||
color: midnightblue;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.dummy-wrapper-text hr {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-main-container">
|
||||
<!-- Title + Explained details of the example -->
|
||||
<div class="dummy-wrapper-text">
|
||||
<h1>🐘 Mastodon embed timeline</h1>
|
||||
<h2>Local timeline</h2>
|
||||
<p>
|
||||
This example shows 20 posts from the following instance:
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.social/public/local"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>mastodon.social</a
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
It has the default parameters and has been initialized with the
|
||||
following script:
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline();
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>
|
||||
To change the current instance and show a different local timeline,
|
||||
for example:
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.online/public/local"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>mastodon.online</a
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
You just need to initialize the script by passing the custom option
|
||||
<strong>instanceUrl</strong> with the value
|
||||
<strong>"https://mastodon.online"</strong> as follows in the example:
|
||||
</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online"
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline -->
|
||||
<div id="mt-container" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
165
examples/multiple-timelines.html
Normal file
165
examples/multiple-timelines.html
Normal file
@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<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" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background: lightgrey;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-main-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.dummy-wrapper-text,
|
||||
.dummy-wrapper-timeline {
|
||||
width: 50%;
|
||||
max-width: 30rem;
|
||||
height: calc(100% - 4rem);
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.dummy-wrapper-text h1,
|
||||
.dummy-wrapper-text h2,
|
||||
.dummy-wrapper-text p {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
.dummy-wrapper-text pre {
|
||||
display: flex;
|
||||
background: lightsteelblue;
|
||||
border-left: 3px solid #563acc;
|
||||
color: midnightblue;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.dummy-wrapper-text hr {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-main-container">
|
||||
<!-- Title + Explained details of the example -->
|
||||
<div class="dummy-wrapper-text">
|
||||
<h1>🐘 Mastodon embed timeline</h1>
|
||||
<h2>Multiple timeline</h2>
|
||||
<p>
|
||||
This example shows 3 local timelines running in the same page:
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.social/public/local"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>mastodon.social</a
|
||||
>
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.online/public/local"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>mastodon.online</a
|
||||
>
|
||||
<br />
|
||||
<a
|
||||
href="https://mstdn.social/public/local"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>mstdn.social</a
|
||||
>
|
||||
</p>
|
||||
<p>It has been initialized with the following script:</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
instanceUrl: "https://mastodon.social",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
instanceUrl: "https://mastodon.online",
|
||||
});
|
||||
|
||||
const myTimeline3 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-03",
|
||||
instanceUrl: "https://mstdn.social",
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline 01 -->
|
||||
<div id="mt-container-01" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline 02 -->
|
||||
<div id="mt-container-02" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline 02 -->
|
||||
<div id="mt-container-03" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
instanceUrl: "https://mastodon.social",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
instanceUrl: "https://mastodon.online",
|
||||
});
|
||||
|
||||
const myTimeline3 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-03",
|
||||
instanceUrl: "https://mstdn.social",
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
117
examples/profile-timeline.html
Normal file
117
examples/profile-timeline.html
Normal file
@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<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" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background: lightgrey;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-main-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.dummy-wrapper-text,
|
||||
.dummy-wrapper-timeline {
|
||||
width: 50%;
|
||||
max-width: 30rem;
|
||||
height: calc(100% - 4rem);
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.dummy-wrapper-text h1,
|
||||
.dummy-wrapper-text h2,
|
||||
.dummy-wrapper-text p {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
.dummy-wrapper-text pre {
|
||||
display: flex;
|
||||
background: lightsteelblue;
|
||||
border-left: 3px solid #563acc;
|
||||
color: midnightblue;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.dummy-wrapper-text hr {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-main-container">
|
||||
<!-- Title + Explained details of the example -->
|
||||
<div class="dummy-wrapper-text">
|
||||
<h1>🐘 Mastodon embed timeline</h1>
|
||||
<h2>Profile timeline</h2>
|
||||
<p>
|
||||
This example shows posts from my Mastodon profile
|
||||
<br />
|
||||
<a
|
||||
href="https://mastodon.online/@idotj"
|
||||
target="_blank"
|
||||
rel="nofollow noopener noreferrer"
|
||||
>@idotj</a
|
||||
>
|
||||
</p>
|
||||
<p>It has been initialized with the following script:</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "profile",
|
||||
userId: "000180745",
|
||||
profileName: "@idotj",
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline -->
|
||||
<div id="mt-container" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline = new MastodonTimeline({
|
||||
instanceUrl: "https://mastodon.online",
|
||||
timelineType: "profile",
|
||||
userId: "000180745",
|
||||
profileName: "@idotj",
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
182
examples/theme-timeline.html
Normal file
182
examples/theme-timeline.html
Normal file
@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<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" />
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
height: 100%;
|
||||
background: lightgrey;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-main-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 2rem;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
.dummy-wrapper-text,
|
||||
.dummy-wrapper-timeline {
|
||||
width: 50%;
|
||||
max-width: 30rem;
|
||||
height: calc(100% - 4rem);
|
||||
padding: 0 1rem;
|
||||
}
|
||||
.dummy-wrapper-text h1,
|
||||
.dummy-wrapper-text h2,
|
||||
.dummy-wrapper-text p {
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
.dummy-wrapper-text pre {
|
||||
display: flex;
|
||||
background: lightsteelblue;
|
||||
border-left: 3px solid #563acc;
|
||||
color: midnightblue;
|
||||
page-break-inside: avoid;
|
||||
font-family: monospace;
|
||||
line-height: 1.5;
|
||||
max-width: 100%;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.dummy-wrapper-text hr {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.dummy-buttons-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.dummy-buttons-container button {
|
||||
display: flex;
|
||||
border-radius: 0.25rem;
|
||||
border: 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
background-color: #6364ff;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.dummy-buttons-container button:hover {
|
||||
background-color: #563acc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-main-container">
|
||||
<!-- Title + Explained details of the example -->
|
||||
<div class="dummy-wrapper-text">
|
||||
<h1>🐘 Mastodon embed timeline</h1>
|
||||
<h2>Light timeline</h2>
|
||||
<p>This example shows a timeline in light color:</p>
|
||||
<p>It has been initialized with the following script:</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
defaultTheme: "light",
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2>Dark timeline</h2>
|
||||
<p>This example shows a timeline in dark color:</p>
|
||||
<p>It has been initialized with the following script:</p>
|
||||
<pre>
|
||||
<code>
|
||||
<script>
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
defaultTheme: "dark",
|
||||
});
|
||||
</script>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2>Theme API</h2>
|
||||
<p>
|
||||
You can change your timeline color calling the function <strong>mtColorTheme()</strong>
|
||||
</p>
|
||||
<div class="dummy-buttons-container">
|
||||
<button onclick="myTimeline1.mtColorTheme('dark')">
|
||||
Switch 1st timeline to dark theme
|
||||
</button>
|
||||
<button onclick="myTimeline2.mtColorTheme('light')">
|
||||
Switch 2nd timeline to light theme
|
||||
</button>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
<button onclick="myTimeline1.mtColorTheme('dark')">
|
||||
Switch 1st timeline to dark theme
|
||||
</button>
|
||||
|
||||
<button onclick="myTimeline2.mtColorTheme('light')">
|
||||
Switch 2nd timeline to light theme
|
||||
</button>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline 01 -->
|
||||
<div id="mt-container-01" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dummy-wrapper-timeline">
|
||||
<!-- Mastodon Timeline 02 -->
|
||||
<div id="mt-container-02" class="mt-container">
|
||||
<div class="mt-body" role="feed">
|
||||
<div class="mt-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JavaScript -->
|
||||
<script src="./js/mastodon-timeline.js"></script>
|
||||
<script>
|
||||
const myTimeline1 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-01",
|
||||
defaultTheme: "light",
|
||||
});
|
||||
|
||||
const myTimeline2 = new MastodonTimeline({
|
||||
mtContainerId: "mt-container-02",
|
||||
defaultTheme: "dark",
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 278 KiB |
@ -1,45 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-theme="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mastodon embed timeline</title>
|
||||
<meta name="author" content="i.j" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="keywords" content="mastodon, embed timeline" />
|
||||
<meta name="description" content="Mastodon embed timeline" />
|
||||
<link rel="shortcut icon" href="#" />
|
||||
<link rel="stylesheet" href="./mastodon-timeline.css" />
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: lightslategray;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
.dummy-wrapper {
|
||||
width: calc(100% - 1rem);
|
||||
max-width: 26rem;
|
||||
height: calc(100% - 3rem);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dummy-wrapper">
|
||||
<div class="mt-container">
|
||||
<div id="mt-body" class="mt-body" role="feed">
|
||||
<div class="loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="./mastodon-timeline.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,78 +1,89 @@
|
||||
/* Mastodon embed feed timeline v3.13.2 */
|
||||
/* Mastodon embed feed timeline v4.0.0 */
|
||||
/* More info at: */
|
||||
/* https://gitlab.com/idotj/mastodon-embed-feed-timeline */
|
||||
|
||||
/* Variables */
|
||||
:root {
|
||||
--text-max-lines: none;
|
||||
.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;
|
||||
}
|
||||
|
||||
/* Theme colors */
|
||||
:root,
|
||||
html[data-theme="light"] {
|
||||
--bg-color: #fff;
|
||||
--bg-hover-color: #d9e1e8;
|
||||
--line-gray-color: #c0cdd9;
|
||||
--contrast-gray-color: #606984;
|
||||
--content-text: #000;
|
||||
--link-color: #3a3bff;
|
||||
--error-text-color: #8b0000;
|
||||
/* Reset CSS */
|
||||
.mt-container button {
|
||||
font: inherit;
|
||||
}
|
||||
html[data-theme="dark"] {
|
||||
--bg-color: #282c37;
|
||||
--bg-hover-color: #313543;
|
||||
--line-gray-color: #393f4f;
|
||||
--contrast-gray-color: #606984;
|
||||
--content-text: #fff;
|
||||
--link-color: #8c8dff;
|
||||
--error-text-color: #fe6c6c;
|
||||
.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(--bg-color);
|
||||
scrollbar-color: var(--line-gray-color) var(--bg-color);
|
||||
scrollbar-width: thin;
|
||||
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(--line-gray-color);
|
||||
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(--line-gray-color);
|
||||
background-color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-container::-webkit-scrollbar-track {
|
||||
background-color: var(--bg-color);
|
||||
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(--bg-color);
|
||||
background-color: var(--mt-color-bg);
|
||||
}
|
||||
.mt-container a:link,
|
||||
.mt-container a:active,
|
||||
.mt-container a {
|
||||
text-decoration: none;
|
||||
color: var(--link-color);
|
||||
color: var(--mt-color-link);
|
||||
}
|
||||
.mt-container a:not(.mt-toot-preview):hover {
|
||||
.mt-container a:not(.mt-post-preview):hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.mt-body {
|
||||
padding: 1rem clamp(0.25rem, 4vw, 1.5rem);
|
||||
padding: 1rem clamp(0.25rem, 4vw, 1rem);
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-body .invisible {
|
||||
font-size: 0;
|
||||
@ -83,45 +94,45 @@ html[data-theme="dark"] {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* Toot container */
|
||||
.mt-toot {
|
||||
/* 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(--line-gray-color);
|
||||
border-bottom: 1px solid var(--mt-color-line-gray);
|
||||
}
|
||||
.mt-toot:hover,
|
||||
.mt-toot:focus {
|
||||
.mt-post:hover,
|
||||
.mt-post:focus {
|
||||
cursor: pointer;
|
||||
background-color: var(--bg-hover-color);
|
||||
background-color: var(--mt-color-bg-hover);
|
||||
}
|
||||
.mt-toot p:last-child {
|
||||
.mt-post p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* User avatar */
|
||||
.mt-toot-avatar {
|
||||
.mt-post-avatar {
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
.mt-toot-avatar-standard {
|
||||
.mt-post-avatar-standard {
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
}
|
||||
.mt-toot-avatar-boosted {
|
||||
.mt-post-avatar-boosted {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
position: relative;
|
||||
}
|
||||
.mt-toot-avatar-image-big img {
|
||||
.mt-post-avatar-image-big img {
|
||||
aspect-ratio: 1/1;
|
||||
width: 2.25rem;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.25rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mt-toot-avatar-image-small img {
|
||||
.mt-post-avatar-image-small img {
|
||||
aspect-ratio: 1/1;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
@ -133,59 +144,56 @@ html[data-theme="dark"] {
|
||||
}
|
||||
|
||||
/* User name and date */
|
||||
.mt-toot-header {
|
||||
.mt-post-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-toot-header-user {
|
||||
.mt-post-header-user {
|
||||
font-weight: 600;
|
||||
margin-top: 0.5rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.mt-toot-header-user > a {
|
||||
.mt-post-header-user > a {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
color: var(--content-text) !important;
|
||||
color: var(--mt-color-content-txt) !important;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.mt-toot-header-date {
|
||||
.mt-post-header-date {
|
||||
font-size: 0.75rem;
|
||||
text-align: right;
|
||||
margin: 0.5rem 0 0 auto;
|
||||
}
|
||||
.mt-toot-header-date > a {
|
||||
color: var(--contrast-gray-color) !important;
|
||||
.mt-post-header-date > a {
|
||||
color: var(--mt-color-contrast-gray) !important;
|
||||
}
|
||||
|
||||
/* Text */
|
||||
.mt-toot-text {
|
||||
.mt-post-txt {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--content-text);
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-toot-text .spoiler-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
.mt-toot-text .spoiler-text-hidden {
|
||||
.mt-post-txt .spoiler-txt-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mt-toot-text.truncate {
|
||||
.mt-post-txt.truncate {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: var(--text-max-lines);
|
||||
-webkit-line-clamp: var(--mt-txt-max-lines);
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.mt-toot-text:not(.truncate) .ellipsis::after {
|
||||
.mt-post-txt:not(.truncate) .ellipsis::after {
|
||||
content: "...";
|
||||
}
|
||||
.mt-toot-text blockquote {
|
||||
border-left: 0.25rem solid var(--line-gray-color);
|
||||
.mt-post-txt blockquote {
|
||||
border-left: 0.25rem solid var(--mt-color-line-gray);
|
||||
margin-left: 0;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
.mt-toot-header-user .custom-emoji,
|
||||
.mt-toot-text .custom-emoji {
|
||||
.mt-post-header-user .mt-custom-emoji,
|
||||
.mt-post-txt .mt-custom-emoji {
|
||||
height: 1.5rem;
|
||||
min-width: 1.5rem;
|
||||
margin-bottom: -0.25rem;
|
||||
@ -193,80 +201,67 @@ html[data-theme="dark"] {
|
||||
}
|
||||
|
||||
/* Poll */
|
||||
.mt-toot-poll {
|
||||
.mt-post-poll {
|
||||
margin-bottom: 1rem;
|
||||
color: var(--content-text);
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-toot-poll ul {
|
||||
.mt-post-poll ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.mt-toot-poll ul li {
|
||||
.mt-post-poll ul li {
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.mt-toot-poll.mt-toot-poll-expired ul li {
|
||||
color: var(--contrast-gray-color);
|
||||
.mt-post-poll.mt-post-poll-expired ul li {
|
||||
color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-toot-poll ul li:not(:last-child) {
|
||||
.mt-post-poll ul li:not(:last-child) {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.mt-toot-poll ul li:before {
|
||||
.mt-post-poll ul li:before {
|
||||
content: "◯";
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
.mt-toot-poll.mt-toot-poll-expired ul li:before {
|
||||
.mt-post-poll.mt-post-poll-expired ul li:before {
|
||||
content: "";
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Medias */
|
||||
.mt-toot-media {
|
||||
.mt-post-media {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-toot-media > .spoiler-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.mt-toot-media-spoiler > img,
|
||||
.mt-toot-media-spoiler > audio,
|
||||
.mt-toot-media-spoiler > video,
|
||||
.mt-toot-media-spoiler > .mt-toot-media-play-icon {
|
||||
.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-toot-media.img-ratio14_7,
|
||||
.mt-toot-media.video-ratio14_7 {
|
||||
padding-top: 56.95%;
|
||||
width: 100%;
|
||||
}
|
||||
.mt-toot-media > audio {
|
||||
.mt-post-media > audio {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.img-ratio14_7 > img,
|
||||
.video-ratio14_7 > img,
|
||||
.video-ratio14_7 > video {
|
||||
.mt-post-media > img,
|
||||
.mt-post-media > video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
color: var(--content-text);
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-toot-media.loading-spinner .mt-toot-media-play-icon {
|
||||
.mt-post-media.mt-loading-spinner .mt-post-media-play-icon {
|
||||
display: none;
|
||||
}
|
||||
.mt-toot-media-play-icon {
|
||||
.mt-post-media-play-icon {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 3rem;
|
||||
@ -279,44 +274,44 @@ html[data-theme="dark"] {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mt-toot-media-play-icon > svg {
|
||||
.mt-post-media-play-icon > svg {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
fill: var(--bg-color);
|
||||
stroke:var(--content-text);
|
||||
fill: var(--mt-color-bg);
|
||||
stroke: var(--mt-color-content-txt);
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
/* Preview link */
|
||||
.mt-toot-preview {
|
||||
.mt-post-preview {
|
||||
min-height: 4rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid var(--line-gray-color);
|
||||
border: 1px solid var(--mt-color-line-gray);
|
||||
border-radius: 0.5rem;
|
||||
color: var(--link-color);
|
||||
color: var(--mt-color-link);
|
||||
font-size: 0.8rem;
|
||||
margin: 1rem 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.mt-toot-preview-image {
|
||||
.mt-post-preview-image {
|
||||
width: 40%;
|
||||
align-self: stretch;
|
||||
}
|
||||
.mt-toot-preview-image img {
|
||||
.mt-post-preview-image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
color: var(--content-text);
|
||||
color: var(--mt-color-content-txt);
|
||||
}
|
||||
.mt-toot-preview-noImage {
|
||||
.mt-post-preview-noImage {
|
||||
width: 40%;
|
||||
font-size: 1.5rem;
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
}
|
||||
.mt-toot-preview-content {
|
||||
.mt-post-preview-content {
|
||||
width: 60%;
|
||||
display: flex;
|
||||
align-self: center;
|
||||
@ -324,59 +319,93 @@ html[data-theme="dark"] {
|
||||
padding: 0.5rem 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.mt-toot-preview-title {
|
||||
.mt-post-preview-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Spoiler button */
|
||||
.spoiler-btn {
|
||||
border-radius: 2px;
|
||||
background-color: var(--line-gray-color);
|
||||
border: 0;
|
||||
color: var(--content-text);
|
||||
font-weight: 700;
|
||||
font-size: 0.7rem;
|
||||
padding: 0 0.35rem;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.25rem;
|
||||
cursor: pointer;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* Counter bar */
|
||||
.mt-toot-counter-bar {
|
||||
.mt-post-counter-bar {
|
||||
display: flex;
|
||||
min-width: 6rem;
|
||||
max-width: 40rem;
|
||||
justify-content: space-between;
|
||||
color: var(--contrast-gray-color);
|
||||
color: var(--mt-color-contrast-gray);
|
||||
}
|
||||
.mt-toot-counter-bar-replies,
|
||||
.mt-toot-counter-bar-reblog,
|
||||
.mt-toot-counter-bar-favorites {
|
||||
.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-toot-counter-bar-replies > svg,
|
||||
.mt-toot-counter-bar-reblog > svg,
|
||||
.mt-toot-counter-bar-favorites > svg {
|
||||
.mt-post-counter-bar-replies > svg,
|
||||
.mt-post-counter-bar-reblog > svg,
|
||||
.mt-post-counter-bar-favorites > svg {
|
||||
width: 1rem;
|
||||
fill: var(--contrast-gray-color);
|
||||
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(--error-text-color);
|
||||
color: var(--mt-color-error-txt);
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
}
|
||||
@ -384,14 +413,15 @@ html[data-theme="dark"] {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.mt-error-message {
|
||||
width: 100%;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.mt-error-message hr {
|
||||
color: var(--line-gray-color);
|
||||
color: var(--mt-color-line-gray);
|
||||
}
|
||||
|
||||
/* Loading spinner */
|
||||
.mt-body > .loading-spinner {
|
||||
.mt-body > .mt-loading-spinner {
|
||||
position: absolute;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
@ -399,7 +429,7 @@ html[data-theme="dark"] {
|
||||
top: calc(50% - 1.5rem);
|
||||
right: calc(50% - 1.5rem);
|
||||
}
|
||||
.loading-spinner {
|
||||
.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;
|
||||
@ -407,11 +437,15 @@ html[data-theme="dark"] {
|
||||
background-size: min(2.5rem, calc(100% - 0.5rem));
|
||||
}
|
||||
|
||||
/* Footer (See more link) */
|
||||
/* Footer */
|
||||
.mt-footer {
|
||||
margin: 1rem auto 2rem auto;
|
||||
padding: 0 2rem;
|
||||
text-align: center;
|
||||
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 */
|
||||
|
File diff suppressed because it is too large
Load Diff
1
src/mastodon-timeline.min.css
vendored
1
src/mastodon-timeline.min.css
vendored
File diff suppressed because one or more lines are too long
1
src/mastodon-timeline.min.js
vendored
1
src/mastodon-timeline.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user