Compare commits

...

36 commits
1.2.0 ... main

Author SHA1 Message Date
Thomas
ca9e903300 Release 1.3.0 2025-04-03 17:50:13 +02:00
Thomas
2861e104da :-\ 2025-04-03 17:48:05 +02:00
Thomas
5208512073 Fix custom emojis not displayed in messages and screen name 2025-04-03 17:36:43 +02:00
Thomas
ee02589df6 Change title for schedule/scheduled pages 2025-04-03 16:35:29 +02:00
Thomas
60a2895b1f Move logout item to the end of the menu 2025-04-03 16:34:58 +02:00
Thomas
4ffe74a73a Display date with browser timezone 2025-04-03 16:06:15 +02:00
Thomas
618da03e0e Add timezone to the date of scheduled messages 2025-04-03 15:24:56 +02:00
Thomas
60b919fd4a Fix issue #13 - Previous scheduled messages are not displayed when scrolling down the list 2025-04-03 11:02:23 +02:00
Thomas
f0881c2d51 Update libs 2025-04-03 10:09:21 +02:00
Thomas
16a398e852 add in autoscript 2024-05-19 10:14:12 +02:00
Thomas
53130908b5 1.2.4 2024-05-19 10:07:38 +02:00
Thomas
3f06bd8b08 Merge branch 'develop' 2024-05-19 10:06:46 +02:00
Thomas
ca3c8c5bd5 default assets 2024-05-19 10:05:48 +02:00
Thomas
7fee848433 Merge branch 'develop' 2024-05-19 08:44:57 +02:00
Thomas
4f5ac293ab add autoscript 2024-05-19 08:44:35 +02:00
Thomas
6f11a93268 Merge branch 'develop' 2024-05-19 08:04:22 +02:00
Thomas
e5f707ff73 Release 1.2.3 2024-05-19 08:04:10 +02:00
Thomas
82ac8422b4 Merge branch 'develop' 2024-05-19 08:03:07 +02:00
Thomas
493b790559 prod 2024-05-19 08:02:43 +02:00
Thomas
f3824010ee layout changes 2024-05-19 08:00:18 +02:00
Thomas
aadcb2e1a8 Merge branch 'develop' 2024-05-19 07:51:56 +02:00
Thomas
e25ac90340 Merge branch 'update_readme' into 'develop'
Update readme

See merge request tom79/fediplan!87
2024-05-18 18:03:40 +00:00
0xd9a
6e6d2cb3a1 Update readme 2024-05-18 18:03:39 +00:00
Thomas
34976a0252 Merge branch 'develop' into 'main'
Release 1.2.2

See merge request tom79/fediplan!86
2024-05-18 17:43:51 +00:00
Thomas
41bf64d7b0 Release 1.2.2 2024-05-18 17:43:51 +00:00
Thomas
2c773d7795 Merge branch 'main' into 'develop'
# Conflicts:
#   public/css/bootstrap-toggle.min.css
#   public/js/bootstrap-toggle.min.js
#   templates/fediplan/about.html.twig
#   templates/fediplan/index.html.twig
#   templates/fediplan/schedule.html.twig
2024-05-18 17:43:10 +00:00
Thomas
477dabc702 Fix layout 2024-05-18 19:40:04 +02:00
Thomas
524917e7ba Merge branch 'develop' into 'main'
Release 1.2.1

See merge request tom79/fediplan!85
2024-05-18 15:23:43 +00:00
Thomas
3a6fed30a6 Release 1.2.1 2024-05-18 15:23:43 +00:00
Thomas
7fa59fb29f -Release 1.2.1 2024-05-18 17:22:28 +02:00
Thomas
c81011b6ce - Fix column 2024-05-18 17:17:57 +02:00
Thomas
92eb140d69 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fediplan!84
2024-05-16 13:41:50 +00:00
Thomas
c307ad0f10 New Crowdin updates 2024-05-16 13:41:50 +00:00
Thomas
7063de4dd2 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fediplan!83
2024-05-16 09:12:23 +00:00
Thomas
4692d5430a New Crowdin updates 2024-05-16 09:12:23 +00:00
Thomas
defb279698 - migrate to boostrap 5.3
- Fix messages not displayed when missing media description
2024-05-16 10:55:16 +02:00
67 changed files with 29585 additions and 19047 deletions

2
.env
View file

@ -15,7 +15,7 @@
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
###> symfony/framework-bundle ###
APP_ENV=dev
APP_ENV=prod
APP_SECRET=7189792ca5da6b84aff72ec1c63d95ae
###< symfony/framework-bundle ###

View file

@ -14,44 +14,60 @@ There are 2 methods to run Fediplan
#### Steps
1. Clone this repo<br>
1. Install required programs
2. Clone this repo<br>
`git clone https://framagit.org/tom79/fediplan.git fediplan`
2. Build the Docker image<br>
`docker build -t fediplan fediplan`
3. Build the Docker image<br>
`docker build --tag fediplan fediplan`
3. Run the docker image<br>
`docker run fediplan`
4. Run the docker image<br>
`docker run --detach --restart unless-stopped --name fediplan fediplan:latest`
4. Find the IP<br>
5. Find the IP<br>
`docker inspect fediplan | grep IPAddress`
- Find 'CONTAINER ID' of fediplan's container<br>
`docker ps | grep fediplan`
- Find IP address of the container<br>
`docker inspect <CONTAINER ID> | grep IPAddress`
5. Open _<ip_address>:8080_ in your web browser
6. Fediplan should be available at _<ip_address>:8080_
### 2. Manual install
#### Required programs
- `git`
- `php 8.3` and some extensions
- `php 8.3` with these extensions:
For Composer
- `openssl`
- `phar`
- `iconv`
- `xml`
- `simplexml`
- `xmlwriter`
For running
- `ctype`
- `curl`
- `dom`
- `fpm`
- `intl`
- `mbstring`
- `simplexml`
- `session`
- `tokenizer`
- `composer` ([getcomposer.org/download](https://getcomposer.org/download/))
#### Steps
1. Clone this repo<br>
1. Install required programs
2. Clone this repo<br>
`git clone https://framagit.org/tom79/fediplan.git fediplan`
2. Change directory to the cloned repo<br>
`cd fediplan`
3. Install vendors<br>
`composer install -o`
`php composer.phar install --optimize-autoloader --working-dir=fediplan`
4. Point your server software to '_public_' folder
4. Point your server software to `fediplan/public` folder
### Support My work
[fedilab.app/page/donations](https://fedilab.app/page/donations/)

10
assets/app.js Normal file
View file

@ -0,0 +1,10 @@
import './bootstrap.js';
/*
* Welcome to your app's main JavaScript file!
*
* This file will be included onto the page via the importmap() Twig function,
* which should already be in your base.html.twig.
*/
import './styles/app.css';
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');

5
assets/bootstrap.js vendored Normal file
View file

@ -0,0 +1,5 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

15
assets/controllers.json Normal file
View file

@ -0,0 +1,15 @@
{
"controllers": {
"@symfony/ux-turbo": {
"turbo-core": {
"enabled": true,
"fetch": "eager"
},
"mercure-turbo-stream": {
"enabled": false,
"fetch": "eager"
}
}
},
"entrypoints": []
}

View file

@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';
/*
* This is an example Stimulus controller!
*
* Any element with a data-controller="hello" attribute will cause
* this controller to be executed. The name "hello" comes from the filename:
* hello_controller.js -> "hello"
*
* Delete this file or adapt it for your use!
*/
export default class extends Controller {
connect() {
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
}
}

1
assets/js/routes.json Normal file
View file

@ -0,0 +1 @@
{"base_url":"","routes":{"load_more":{"tokens":[["variable","\/","[^\/]++","max_id",true],["text","\/scheduled\/messages"],["variable","\/","[^\/]++","_locale",true]],"defaults":{"max_id":null,"_locale":""},"requirements":[],"hosttokens":[],"methods":[],"schemes":[]},"delete_message":{"tokens":[["variable","\/","[^\/]++","id",true],["text","\/scheduled\/delete\/messages"],["variable","\/","fr|en|nl|pt-PT|pt-BR|de|ar|it|ca|ja|pl|ru|uk","_locale",true]],"defaults":{"_locale":"en","id":null},"requirements":{"_locale":"fr|en|nl|pt-PT|pt-BR|de|ar|it|ca|ja|pl|ru|uk"},"hosttokens":[],"methods":["POST"],"schemes":[]}},"prefix":"","host":"localhost","port":"","scheme":"http","locale":""}

View file

@ -0,0 +1 @@
{"base_url":"","routes":{"load_more":{"tokens":[["variable","\/","[^\/]++","max_id",true],["text","\/scheduled\/messages"],["variable","\/","[^\/]++","_locale",true]],"defaults":{"max_id":null,"_locale":""},"requirements":[],"hosttokens":[],"methods":[],"schemes":[]},"delete_message":{"tokens":[["variable","\/","[^\/]++","id",true],["text","\/scheduled\/delete\/messages"],["variable","\/","fr|en|nl|pt-PT|pt-BR|de|ar|it|ca|ja|pl|ru|uk","_locale",true]],"defaults":{"_locale":"en","id":null},"requirements":{"_locale":"fr|en|nl|pt-PT|pt-BR|de|ar|it|ca|ja|pl|ru|uk"},"hosttokens":[],"methods":["POST"],"schemes":[]}},"prefix":"","host":"localhost","port":"","scheme":"http","locale":""}

3
assets/styles/app.css Normal file
View file

@ -0,0 +1,3 @@
body {
background-color: skyblue;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

22
assets/vendor/installed.php vendored Normal file
View file

@ -0,0 +1,22 @@
<?php return array (
'@hotwired/stimulus' =>
array (
'version' => '3.2.2',
'dependencies' =>
array (
),
'extraFiles' =>
array (
),
),
'@hotwired/turbo' =>
array (
'version' => '7.3.0',
'dependencies' =>
array (
),
'extraFiles' =>
array (
),
),
);

View file

@ -40,8 +40,9 @@
"symfony/validator": "7.0.*",
"symfony/web-link": "7.0.*",
"symfony/yaml": "7.0.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0"
"twig/extra-bundle": "^3.20",
"twig/intl-extra": "^3.20",
"twig/twig": "v3.15.0"
},
"config": {
"allow-plugins": {
@ -75,7 +76,9 @@
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"importmap:install": "symfony-cmd"
"assets:install --symlink public": "symfony-cmd",
"importmap:install": "symfony-cmd",
"asset-map:compile": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"

1264
composer.lock generated

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,57 +1,268 @@
/*!
* Bootstrap Reboot v4.1.3 (https://getbootstrap.com/)
* Copyright 2011-2018 The Bootstrap Authors
* Copyright 2011-2018 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
:root,
[data-bs-theme=light] {
--bs-blue: #0d6efd;
--bs-indigo: #6610f2;
--bs-purple: #6f42c1;
--bs-pink: #d63384;
--bs-red: #dc3545;
--bs-orange: #fd7e14;
--bs-yellow: #ffc107;
--bs-green: #198754;
--bs-teal: #20c997;
--bs-cyan: #0dcaf0;
--bs-black: #000;
--bs-white: #fff;
--bs-gray: #6c757d;
--bs-gray-dark: #343a40;
--bs-gray-100: #f8f9fa;
--bs-gray-200: #e9ecef;
--bs-gray-300: #dee2e6;
--bs-gray-400: #ced4da;
--bs-gray-500: #adb5bd;
--bs-gray-600: #6c757d;
--bs-gray-700: #495057;
--bs-gray-800: #343a40;
--bs-gray-900: #212529;
--bs-primary: #0d6efd;
--bs-secondary: #6c757d;
--bs-success: #198754;
--bs-info: #0dcaf0;
--bs-warning: #ffc107;
--bs-danger: #dc3545;
--bs-light: #f8f9fa;
--bs-dark: #212529;
--bs-primary-rgb: 13, 110, 253;
--bs-secondary-rgb: 108, 117, 125;
--bs-success-rgb: 25, 135, 84;
--bs-info-rgb: 13, 202, 240;
--bs-warning-rgb: 255, 193, 7;
--bs-danger-rgb: 220, 53, 69;
--bs-light-rgb: 248, 249, 250;
--bs-dark-rgb: 33, 37, 41;
--bs-primary-text-emphasis: #052c65;
--bs-secondary-text-emphasis: #2b2f32;
--bs-success-text-emphasis: #0a3622;
--bs-info-text-emphasis: #055160;
--bs-warning-text-emphasis: #664d03;
--bs-danger-text-emphasis: #58151c;
--bs-light-text-emphasis: #495057;
--bs-dark-text-emphasis: #495057;
--bs-primary-bg-subtle: #cfe2ff;
--bs-secondary-bg-subtle: #e2e3e5;
--bs-success-bg-subtle: #d1e7dd;
--bs-info-bg-subtle: #cff4fc;
--bs-warning-bg-subtle: #fff3cd;
--bs-danger-bg-subtle: #f8d7da;
--bs-light-bg-subtle: #fcfcfd;
--bs-dark-bg-subtle: #ced4da;
--bs-primary-border-subtle: #9ec5fe;
--bs-secondary-border-subtle: #c4c8cb;
--bs-success-border-subtle: #a3cfbb;
--bs-info-border-subtle: #9eeaf9;
--bs-warning-border-subtle: #ffe69c;
--bs-danger-border-subtle: #f1aeb5;
--bs-light-border-subtle: #e9ecef;
--bs-dark-border-subtle: #adb5bd;
--bs-white-rgb: 255, 255, 255;
--bs-black-rgb: 0, 0, 0;
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
--bs-body-font-family: var(--bs-font-sans-serif);
--bs-body-font-size: 1rem;
--bs-body-font-weight: 400;
--bs-body-line-height: 1.5;
--bs-body-color: #212529;
--bs-body-color-rgb: 33, 37, 41;
--bs-body-bg: #fff;
--bs-body-bg-rgb: 255, 255, 255;
--bs-emphasis-color: #000;
--bs-emphasis-color-rgb: 0, 0, 0;
--bs-secondary-color: rgba(33, 37, 41, 0.75);
--bs-secondary-color-rgb: 33, 37, 41;
--bs-secondary-bg: #e9ecef;
--bs-secondary-bg-rgb: 233, 236, 239;
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
--bs-tertiary-color-rgb: 33, 37, 41;
--bs-tertiary-bg: #f8f9fa;
--bs-tertiary-bg-rgb: 248, 249, 250;
--bs-heading-color: inherit;
--bs-link-color: #0d6efd;
--bs-link-color-rgb: 13, 110, 253;
--bs-link-decoration: underline;
--bs-link-hover-color: #0a58ca;
--bs-link-hover-color-rgb: 10, 88, 202;
--bs-code-color: #d63384;
--bs-highlight-color: #212529;
--bs-highlight-bg: #fff3cd;
--bs-border-width: 1px;
--bs-border-style: solid;
--bs-border-color: #dee2e6;
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
--bs-border-radius: 0.375rem;
--bs-border-radius-sm: 0.25rem;
--bs-border-radius-lg: 0.5rem;
--bs-border-radius-xl: 1rem;
--bs-border-radius-xxl: 2rem;
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
--bs-border-radius-pill: 50rem;
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
--bs-focus-ring-width: 0.25rem;
--bs-focus-ring-opacity: 0.25;
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
--bs-form-valid-color: #198754;
--bs-form-valid-border-color: #198754;
--bs-form-invalid-color: #dc3545;
--bs-form-invalid-border-color: #dc3545;
}
[data-bs-theme=dark] {
color-scheme: dark;
--bs-body-color: #dee2e6;
--bs-body-color-rgb: 222, 226, 230;
--bs-body-bg: #212529;
--bs-body-bg-rgb: 33, 37, 41;
--bs-emphasis-color: #fff;
--bs-emphasis-color-rgb: 255, 255, 255;
--bs-secondary-color: rgba(222, 226, 230, 0.75);
--bs-secondary-color-rgb: 222, 226, 230;
--bs-secondary-bg: #343a40;
--bs-secondary-bg-rgb: 52, 58, 64;
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
--bs-tertiary-color-rgb: 222, 226, 230;
--bs-tertiary-bg: #2b3035;
--bs-tertiary-bg-rgb: 43, 48, 53;
--bs-primary-text-emphasis: #6ea8fe;
--bs-secondary-text-emphasis: #a7acb1;
--bs-success-text-emphasis: #75b798;
--bs-info-text-emphasis: #6edff6;
--bs-warning-text-emphasis: #ffda6a;
--bs-danger-text-emphasis: #ea868f;
--bs-light-text-emphasis: #f8f9fa;
--bs-dark-text-emphasis: #dee2e6;
--bs-primary-bg-subtle: #031633;
--bs-secondary-bg-subtle: #161719;
--bs-success-bg-subtle: #051b11;
--bs-info-bg-subtle: #032830;
--bs-warning-bg-subtle: #332701;
--bs-danger-bg-subtle: #2c0b0e;
--bs-light-bg-subtle: #343a40;
--bs-dark-bg-subtle: #1a1d20;
--bs-primary-border-subtle: #084298;
--bs-secondary-border-subtle: #41464b;
--bs-success-border-subtle: #0f5132;
--bs-info-border-subtle: #087990;
--bs-warning-border-subtle: #997404;
--bs-danger-border-subtle: #842029;
--bs-light-border-subtle: #495057;
--bs-dark-border-subtle: #343a40;
--bs-heading-color: inherit;
--bs-link-color: #6ea8fe;
--bs-link-hover-color: #8bb9fe;
--bs-link-color-rgb: 110, 168, 254;
--bs-link-hover-color-rgb: 139, 185, 254;
--bs-code-color: #e685b5;
--bs-highlight-color: #dee2e6;
--bs-highlight-bg: #664d03;
--bs-border-color: #495057;
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
--bs-form-valid-color: #75b798;
--bs-form-valid-border-color: #75b798;
--bs-form-invalid-color: #ea868f;
--bs-form-invalid-border-color: #ea868f;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@-ms-viewport {
width: device-width;
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
margin: 1rem 0;
color: inherit;
border: 0;
border-top: var(--bs-border-width) solid;
opacity: 0.25;
}
h1, h2, h3, h4, h5, h6 {
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
color: var(--bs-heading-color);
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
@ -59,13 +270,12 @@ p {
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
@ -74,6 +284,11 @@ address {
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
@ -93,7 +308,7 @@ dt {
}
dd {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
margin-left: 0;
}
@ -101,118 +316,139 @@ blockquote {
margin: 0 0 1rem;
}
dfn {
font-style: italic;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
font-size: 0.875em;
}
mark {
padding: 0.1875em;
color: var(--bs-highlight-color);
background-color: var(--bs-highlight-bg);
}
sub,
sup {
position: relative;
font-size: 75%;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
bottom: -0.25em;
}
sup {
top: -.5em;
top: -0.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:hover {
color: #0056b3;
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
a:hover {
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-family: var(--bs-font-monospace);
font-size: 1em;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
-ms-overflow-style: scrollbar;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: var(--bs-code-color);
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.1875rem 0.375rem;
font-size: 0.875em;
color: var(--bs-body-bg);
background-color: var(--bs-body-color);
border-radius: 0.25rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
img,
svg {
overflow: hidden;
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: var(--bs-secondary-color);
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
button:focus:not(:focus-visible) {
outline: 0;
}
input,
@ -226,46 +462,45 @@ textarea {
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
[role=button] {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
display: none !important;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
@ -277,34 +512,55 @@ fieldset {
}
legend {
display: block;
float: left;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
color: inherit;
white-space: normal;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
progress {
vertical-align: baseline;
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
::-webkit-inner-spin-button {
height: auto;
}
[type="search"] {
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
::-webkit-color-swatch-wrapper {
padding: 0;
}
::-webkit-file-upload-button {
@ -312,20 +568,30 @@ progress {
-webkit-appearance: button;
}
::file-selector-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

14
public/css/bootstrap-toggle.min.css vendored Normal file
View file

@ -0,0 +1,14 @@
/* Copyright Notice
* bootstrap5-toggle v5.1.1
* https://palcarazm.github.io/bootstrap5-toggle/
* @author 2011-2014 Min Hur (https://github.com/minhur)
* @author 2018-2019 Brent Ely (https://github.com/gitbrent)
* @author 2022 Pablo Alcaraz Martínez (https://github.com/palcarazm)
* @funding GitHub Sponsors
* @see https://github.com/sponsors/palcarazm
* @license MIT
* @see https://github.com/palcarazm/bootstrap5-toggle/blob/master/LICENSE
*/
.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}.toggle{position:relative;overflow:hidden}.toggle:focus>.toggle-group>.btn,.toggle:hover>.toggle-group>.btn{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.toggle:focus>.toggle-group>.toggle-handle,.toggle:hover>.toggle-group>.toggle-handle{background-color:var(--bs-light);opacity:.5}.toggle>input[type=checkbox]{display:none}.toggle>.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;user-select:none;-moz-user-select:none;-webkit-user-select:none}.toggle>.toggle-group>span{cursor:pointer}.toggle.off>.toggle-group{left:-100%}.toggle.indeterminate>.toggle-group{left:-50%}.toggle>.toggle-group>.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}.toggle>.toggle-group>.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}.toggle>.toggle-group>.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:var(--bs-light);border-color:var(--bs-light)}.input-group .toggle>.toggle-group>.toggle-off,.input-group .toggle>.toggle-group>.toggle-on{position:absolute}.toggle:not(:hover):not(:focus).btn-outline-primary>.toggle-group>.toggle-handle{background-color:var(--bs-primary);border-color:var(--bs-primary)}.toggle:not(:hover):not(:focus).btn-outline-secondary>.toggle-group>.toggle-handle{background-color:var(--bs-secondary);border-color:var(--bs-secondary)}.toggle:not(:hover):not(:focus).btn-outline-success>.toggle-group>.toggle-handle{background-color:var(--bs-success);border-color:var(--bs-success)}.toggle:not(:hover):not(:focus).btn-outline-danger>.toggle-group>.toggle-handle{background-color:var(--bs-danger);border-color:var(--bs-danger)}.toggle:not(:hover):not(:focus).btn-outline-warning>.toggle-group>.toggle-handle{background-color:var(--bs-warning);border-color:var(--bs-warning)}.toggle:not(:hover):not(:focus).btn-outline-info>.toggle-group>.toggle-handle{background-color:var(--bs-info);border-color:var(--bs-info)}.toggle:not(:hover):not(:focus).btn-outline-light>.toggle-group>.toggle-handle{background-color:var(--bs-light);border-color:var(--bs-light)}.toggle:not(:hover):not(:focus).btn-outline-dark>.toggle-group>.toggle-handle{background-color:var(--bs-dark);border-color:var(--bs-dark)}.toggle.btn{min-width:3.7rem;min-height:2.15rem}.toggle>.toggle-group>.toggle-on.btn{padding-right:1.5rem}.toggle>.toggle-group>.toggle-off.btn{padding-left:1.5rem}.toggle.btn-lg{min-width:5rem;min-height:2.815rem}.toggle>.toggle-group>.toggle-on.btn-lg{padding-right:2rem}.toggle>.toggle-group>.toggle-off.btn-lg{padding-left:2rem}.toggle>.toggle-group>.toggle-handle.btn-lg{width:2.5rem}.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}.toggle>.toggle-group>.toggle-on.btn-sm{padding-right:1rem}.toggle>.toggle-group>.toggle-off.btn-sm{padding-left:1rem}.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}.toggle>.toggle-group>.toggle-on.btn-xs{padding-right:.8rem}.toggle>.toggle-group>.toggle-off.btn-xs{padding-left:.8rem}
/*# sourceMappingURL=bootstrap5-toggle.min.css.map */

16439
public/css/bootstrap.css vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,42 +0,0 @@
/*\
|*| ========================================================================
|*| Bootstrap Toggle: bootstrap4-toggle.css v3.5.0
|*| https://gitbrent.github.io/bootstrap-toggle/
|*| ========================================================================
|*| Copyright 2018-2019 Brent Ely
|*| Licensed under MIT
|*| ========================================================================
\*/
.btn-group-xs>.btn,.btn-xs{padding:.35rem .4rem .25rem;font-size:.875rem;line-height:.5;border-radius:.2rem}
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-1.25rem;margin-right:.35rem}
.toggle{position:relative;overflow:hidden}
.toggle.btn.btn-light,.toggle.btn.btn-outline-light{border-color:rgba(0,0,0,.15)}
.toggle input[type=checkbox]{display:none}
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
.toggle-group label,.toggle-group span{cursor:pointer}
.toggle.off .toggle-group{left:-100%}
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0;box-shadow:none}
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px;background-color:#fff}
.toggle.btn-outline-primary .toggle-handle{background-color:var(--primary);border-color:var(--primary)}
.toggle.btn-outline-secondary .toggle-handle{background-color:var(--secondary);border-color:var(--secondary)}
.toggle.btn-outline-success .toggle-handle{background-color:var(--success);border-color:var(--success)}
.toggle.btn-outline-danger .toggle-handle{background-color:var(--danger);border-color:var(--danger)}
.toggle.btn-outline-warning .toggle-handle{background-color:var(--warning);border-color:var(--warning)}
.toggle.btn-outline-info .toggle-handle{background-color:var(--info);border-color:var(--info)}
.toggle.btn-outline-light .toggle-handle{background-color:var(--light);border-color:var(--light)}
.toggle.btn-outline-dark .toggle-handle{background-color:var(--dark);border-color:var(--dark)}
.toggle[class*=btn-outline]:hover .toggle-handle{background-color:var(--light);opacity:.5}
.toggle.btn{min-width:3.7rem;min-height:2.15rem}
.toggle-on.btn{padding-right:1.5rem}
.toggle-off.btn{padding-left:1.5rem}
.toggle.btn-lg{min-width:5rem;min-height:2.815rem}
.toggle-on.btn-lg{padding-right:2rem}
.toggle-off.btn-lg{padding-left:2rem}
.toggle-handle.btn-lg{width:2.5rem}
.toggle.btn-sm{min-width:3.125rem;min-height:1.938rem}
.toggle-on.btn-sm{padding-right:1rem}
.toggle-off.btn-sm{padding-left:1rem}
.toggle.btn-xs{min-width:2.19rem;min-height:1.375rem}
.toggle-on.btn-xs{padding-right:.8rem}
.toggle-off.btn-xs{padding-left:.8rem}

14
public/js/bootstrap-toggle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4447
public/js/bootstrap.esm.js vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

7
public/js/bootstrap.esm.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

8020
public/js/bootstrap.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,11 +0,0 @@
/*\
|*| ========================================================================
|*| Bootstrap Toggle: bootstrap4-toggle.js v3.5.0
|*| https://gitbrent.github.io/bootstrap-toggle/
|*| ========================================================================
|*| Copyright 2018-2019 Brent Ely
|*| Licensed under MIT
|*| ========================================================================
\*/
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="3.5.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b),e=a('<span class="toggle-handle btn btn-light">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle" role="button">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),a||this.trigger()},c.prototype.off=function(a){if(this.$element.prop("disabled"))return!1;this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),a||this.trigger()},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){a(this).find("input[type=checkbox]").bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
//# sourceMappingURL=bootstrap4-toggle.min.js.map

View file

@ -254,8 +254,9 @@ class FediPlanController extends AbstractController
$form = $this->createForm(ComposeType::class, $compose, ['user' => $this->getUser()]);
}
}
$user = $this->getUser();
/** @var $user MastodonAccount */
$user = $this->getUser();
return $this->render("fediplan/schedule.html.twig", [
'form' => $form->createView(),
@ -273,7 +274,8 @@ class FediPlanController extends AbstractController
)]
public function scheduled(): Response
{
return $this->render("fediplan/scheduled.html.twig");
$user = $this->getUser();
return $this->render("fediplan/scheduled.html.twig", [ 'instance' => $user->getInstance(),]);
}
@ -282,21 +284,22 @@ class FediPlanController extends AbstractController
name: 'load_more',
options: ['expose' => true]
)]
public function loadMoreAction(Mastodon_api $mastodon_api, string $max_id = null): JsonResponse
public function loadMoreAction(Mastodon_api $mastodon_api, ?string $max_id = null , int $limit = 10): JsonResponse
{
/** @var $user MastodonAccount */
$user = $this->getUser();
$mastodon_api->set_url("https://" . $user->getInstance());
$token = explode(" ", $user->getToken())[1];
$type = explode(" ", $user->getToken())[0];
$mastodon_api->set_token($token, $type);
$params = [];
$params['limit'] = $limit;
if ($max_id != null) {
$params['max_id'] = $max_id;
}
$scheduled_reply = $mastodon_api->get_scheduled($params);
$statuses = $mastodon_api->getScheduledStatuses($scheduled_reply['response'], $this->getUser());
$data['max_id'] = $scheduled_reply['max_id'];
$statuses = $mastodon_api->getScheduledStatuses($scheduled_reply['response'], $user);
$data['max_id'] = $statuses[count($statuses)-1]->getId();
$data['html'] = $this->renderView('fediplan/Ajax/layout.html.twig', ['statuses' => $statuses]);
return new JsonResponse($data);
}
@ -309,7 +312,7 @@ class FediPlanController extends AbstractController
defaults: ['_locale'=>'en'],
methods: ['POST']
)]
public function deleteMessage(Mastodon_api $mastodon_api, string $id = null): JsonResponse
public function deleteMessage(Mastodon_api $mastodon_api, ?string $id = null): JsonResponse
{
$user = $this->getUser();
$mastodon_api->set_url("https://" . $user->getInstance());

View file

@ -330,7 +330,7 @@ class MastodonAccount implements UserInterface
public function addField(CustomField $field): self
{
if (in_array($field, $this->Fields) !== false) {
if (in_array($field, $this->Fields) === false) {
$this->Fields[] = $field;
$field->setMastodonAccount($this);
}
@ -357,7 +357,7 @@ class MastodonAccount implements UserInterface
public function addEmoji(Emoji $emoji): self
{
if (in_array($emoji, $this->Emojis) !== false) {
if (in_array($emoji, $this->Emojis) === false) {
$this->Emojis[] = $emoji;
$emoji->setMastodonAccount($this);
}

View file

@ -1556,6 +1556,8 @@ class Mastodon_api
$attachment->setMeta(serialize($_m['meta']));
if ($_m['description'])
$attachment->setDescription($_m['description']);
else
$attachment->setDescription("");
$media_attachments[] = $attachment;
}
$status->setMediaAttachments($media_attachments);

View file

@ -1,6 +1,6 @@
{% trans_default_domain 'fediplan' %}
<!DOCTYPE html>
<html lang="en">
<html lang="{{ app.request.locale }}" {% if app.request.locale == 'ar'%}dir="rtl"{% endif %}>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
@ -67,6 +67,7 @@
{% block javascripts %}
<script src="{{ asset('js/jquery.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.bundle.min.js') }}"></script>
{% endblock %}
</body>
</html>

View file

@ -26,16 +26,16 @@
{% for media in status.getMediaAttachments() %}
<img class="" width="150" src="{{ media.url }}"
style=" border-radius: 5%; margin: 5px;"
{% if media.getDescription is not null %}
alt="{{ media.getDescription() }}"
title="{{ media.getDescription() }}"
{% if media.description is defined and media.description is not empty %}
alt="{{ media.description }}"
title="{{ media.description }}"
{% endif %}
/>
{% endfor %}
</div>
</div>
{% endif %}
<div class="card-footer">
<div class="card-footer text-body-secondary">
<small class="text-muted">
{% if status.visibility == "public" %}
<i class="fa fa-globe"></i>
@ -46,8 +46,8 @@
{% elseif status.visibility == "direct" %}
<i class="fa fa-envelope"></i>
{% endif %}
</small> - {{ status.scheduledAt | date('d/m/y H:i') }}
<button class="btn btn-danger small" data-record-id="{{ status.getId() }}" style="position: absolute;right: 5px;bottom: 5px;"
</small> - <span class="date-UTC"> {{ status.scheduledAt | date('Y-m-d H:m:s') }}</span>
<button class="btn btn-danger btn-sm" data-record-id="{{ status.getId() }}" style="position: absolute;right: 5px;bottom: 5px;"
{% if status.content is not null %}
data-record-title="{{ status.content }} - {{ status.scheduledAt | date('d/m/y H:m') }}"
@ -55,7 +55,7 @@
data-record-title="{{ status.scheduledAt | date('d/m/y H:m') }}"
{% endif %}
data-toggle="modal" data-target="#confirm-delete"
data-bs-toggle="modal" data-bs-target="#confirm-delete"
>X</button>
</div>
</div>

View file

@ -6,8 +6,8 @@
{% include 'nav.html.twig' %}
<h1>{{ 'common.about'|trans }}</h1>
<div class="row well">
<div class="col-md-8 jumbotron">
<div class="row ">
<div class="col-md-8 alert alert-secondary" role="alert">
{{ 'page.about.scheduling'|trans |raw}}
</div>
</div>

View file

@ -12,13 +12,11 @@
{{ form_errors(form) }}
{% if flow.getCurrentStepNumber() == 1 %}
<div class="row">
<div class=" col-md-4">
<div class="col-md-4">
<div class="form-group has-feedback">
{{ form_label(form.host) }}
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1"><i class="fa fa-globe"></i></span>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1"><i class="fa fa-globe"></i></span>
{{ form_widget(form.host, {'attr': {'class': 'form-control'}}) }}
</div>
{% if not form.host.vars.errors is empty %}
@ -37,17 +35,15 @@
<div class="alert alert-warning">
{{ 'messages.login_authorization'|trans }}
</div>
<a href="{{ urlToMastodon }}" target="_blank" class="btn btn-default"> {{ 'messages.authorization_get'|trans }}</a>
<a href="{{ urlToMastodon }}" target="_blank" class="btn btn-secondary"> {{ 'messages.authorization_get'|trans }}</a>
</div>
</div>
<div class="row">
<div class=" col-md-4">
<div class="col-md-4">
<div class="form-group has-feedback">
{{ form_label(form.code) }}
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1"><i class="fa fa-key"></i></span>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1"><i class="fa fa-key"></i></span>
{{ form_widget(form.code, {'attr': {'class': 'form-control'}}) }}
</div>
@ -75,7 +71,7 @@
<blockquote class="blockquote text-center" style="margin-top: 50px;">
<p class="mb-0">{{ 'page.index.about'|trans |raw}}</p>
<p>{{ 'page.index.data'|trans |raw}}</p>
<footer class="blockquote-footer">FediPlan 1.2</footer>
<footer class="blockquote-footer">FediPlan 1.3.0</footer>
</blockquote>
{{ form_end(form) }}

View file

@ -5,7 +5,7 @@
{% block content %}
{% set instanceConfiguration = app.session.get("instance").getConfiguration() %}
{% include 'nav.html.twig' %}
<h3>Schedule for <i><img class="" width="30" src="{{ app.user.avatar }}" alt="{{ app.user.avatar }}"/> {{ convertAccountEmoji(app.user, app.user.displayName) | raw }} (@{{ app.user.acct}}@{{ instance }})</i></h3>
<h3>{{ 'common.schedule'|trans }} <span class="border rounded border-light" style="padding-bottom: 5px;padding-left: 5px;padding-right: 5px; margin-right: 5px;"><img width="30" src="{{ app.user.avatar }}" alt="{{ app.user.avatar }}"/> {{ convertAccountEmoji(app.user, app.user.displayName) | raw }} </span><small><span class="badge text-bg-light">@{{ app.user.acct}}@{{ instance }}</span></small></h3>
{% for type, messages in app.session.flashbag.all() %}
{% for message in messages %}
@ -54,13 +54,13 @@
</div>
<div class="row">
<div class="col-md-4 col-4" style="margin-top: 20px;">
<div class="col-md-4" style="margin-top: 20px;">
<div class="form-inline has-feedback">
<label for="count">{{ 'common.counter'|trans }}</label>&nbsp;&nbsp;<span id="count" >0</span>
&nbsp;/{{ instanceConfiguration.statuses.maxCharacters }}
</div>
</div>
<div class=" col-md-4 col-4" style="margin-top: 20px;">
<div class=" col-md-4" style="margin-top: 20px;">
<div class="form-inline has-feedback">
{{ form_label(form.visibility) }}&nbsp;&nbsp;
{{ form_widget(form.visibility, {'attr': {'class': 'form-control'}}) }}
@ -73,10 +73,10 @@
{% endif %}
</div>
</div>
<div class=" col-md-4 col-4" style="margin-top: 20px;">
<div class=" col-md-4" style="margin-top: 20px;">
<div class="form-inline has-feedback">
{{ form_label(form.sensitive) }}&nbsp;&nbsp;
{{ form_widget(form.sensitive, {'attr': {'class': 'form-control','data-toggle':'toggle', 'data-on': 'common.yes'|trans , 'data-off':'common.no'|trans}}) }}
{{ form_widget(form.sensitive, {'attr': {'class': 'form-control','data-toggle':'toggle', 'data-onlabel': 'common.yes'|trans , 'data-offlabel':'common.no'|trans}}) }}
{% if not form.sensitive.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in form.sensitive.vars.errors %}
@ -88,7 +88,7 @@
</div>
</div>
<div class="row" style="margin-top: 20px;">
<div class=" col-md-5 col-6">
<div class=" col-md-5">
<div class="form-group has-feedback">
{{ form_label(form.scheduled_at) }}
{{ form_widget(form.scheduled_at, {'attr': {'class': 'form-control'}}) }}
@ -101,7 +101,7 @@
{% endif %}
</div>
</div>
<div class=" col-md-5 col-4">
<div class=" col-md-5">
<div class="form-group has-feedback">
{{ form_label(form.timeZone) }}
{{ form_widget(form.timeZone, {'attr': {'class': 'form-control'}}) }}
@ -114,7 +114,7 @@
{% endif %}
</div>
</div>
<div class="col-md-2 col-2">
<div class="col-md-2">
<label for="count">{{ 'common.poll'|trans }}</label>&nbsp;&nbsp;
<span id="poll_switch" class="form-control" style="text-align: center;cursor:pointer;" > <i class="fa fa-tasks fa-fw"></i></span>
@ -122,56 +122,56 @@
</div>
<div id="poll_container" class="d-none">
<ul class="options"
data-prototype="{{ form_widget(form.poll_options.vars.prototype)|e('html_attr') }}">
{% for option in form.poll_options %}
{{ form_widget(option) }}
{% if not option.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in option.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
{% endfor %}
</ul>
<div class="row">
<div class=" col-md-12">
<div class="row">
<div class=" col-md-4">
{{ form_label(form.poll_multiple) }}
{{ form_widget(form.poll_multiple, {'attr': {'class': 'form-control','data-toggle':'toggle', 'data-on': 'common.yes'|trans , 'data-off':'common.no'|trans}}) }}
{% if not form.poll_multiple.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in form.poll_multiple.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
</div>
<div class=" col-md-4">
<div class="form-inline has-feedback">
{{ form_label(form.poll_expires_at) }}&nbsp;&nbsp;&nbsp;
{{ form_widget(form.poll_expires_at, {'attr': {'class': 'form-control'}}) }}
{% if not form.poll_expires_at.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in form.poll_expires_at.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
<ul class="options"
data-prototype="{{ form_widget(form.poll_options.vars.prototype)|e('html_attr') }}">
{% for option in form.poll_options %}
{{ form_widget(option) }}
{% if not option.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in option.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
{% endfor %}
</ul>
<div class="row">
<div class=" col-md-12">
<div class="row">
<div class=" col-md-4">
{{ form_label(form.poll_multiple) }}
{{ form_widget(form.poll_multiple, {'attr': {'class': 'form-control ','data-toggle':'skip-toggle', 'data-onlabel': 'common.yes'|trans , 'data-offlabel':'common.no'|trans}}) }}
{% if not form.poll_multiple.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in form.poll_multiple.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
</div>
<div class=" col-md-4">
<div class="form-inline has-feedback">
{{ form_label(form.poll_expires_at) }}&nbsp;&nbsp;&nbsp;
{{ form_widget(form.poll_expires_at, {'attr': {'class': 'form-control'}}) }}
{% if not form.poll_expires_at.vars.errors is empty %}
<span class="badge badge-danger">
{% for errorItem in form.poll_expires_at.vars.errors %}
{{ errorItem.message }}
{% endfor %}
</span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container" style="margin-bottom: 30px;" id="media_container"></div>
<div class="container" style="margin-bottom: 30px;margin-top: 50px;" id="media_container"></div>
</div>
@ -236,11 +236,12 @@
<link rel="stylesheet" href="{{ asset('js/jQuery-File-Upload-10.1.0/css/doka.min.css') }}">
<link rel="stylesheet" href="{{ asset('js/jQuery-File-Upload-10.1.0/css/blueimp-gallery.min.css') }}">
<link rel="stylesheet" href="{{ asset('js/jQuery-File-Upload-10.1.0/css/jquery.fileupload.css') }}">
<link rel="stylesheet" href="{{ asset('css/bootstrap4-toggle.min.css') }}">
<link rel="stylesheet" href="{{ asset('css/bootstrap-toggle.min.css') }}">
<link rel="stylesheet" href="{{ asset('css/emojionearea.css') }}">
{% endblock %}
{% block javascripts %}
{{ parent() }}
<!-- The blueimp Gallery widget -->
<div
id="blueimp-gallery"
@ -277,7 +278,7 @@
<td>
{% if (!o.options.autoUpload && o.options.edit && o.options.loadImageFileTypes.test(file.type)) { %}
<button class="btn btn-success edit" data-index="{%=i%}" disabled
data-toggle="tooltip" data-placement="top" title="{% endverbatim %}{{ 'page.schedule.form.edit_media'|trans }} {% verbatim %}"
data-bs-toggle="tooltip" data-placement="top" title="{% endverbatim %}{{ 'page.schedule.form.edit_media'|trans }} {% verbatim %}"
>
<i class="glyphicon glyphicon-edit"></i>
<span>{% endverbatim %}{{ 'common.edit'|trans }} {% verbatim %}</span>
@ -285,7 +286,7 @@
{% } %}
{% if (!i && !o.options.autoUpload) { %}
<button class="btn btn-primary start" disabled
data-toggle="tooltip" data-placement="top" title="{% endverbatim %}{{ 'page.schedule.form.upload_media'|trans }} {% verbatim %}"
data-bs-toggle="tooltip" data-placement="top" title="{% endverbatim %}{{ 'page.schedule.form.upload_media'|trans }} {% verbatim %}"
>
<i class="glyphicon glyphicon-upload"></i>
<span> {% endverbatim %} {{ 'common.start'|trans }} {% verbatim %} </span>
@ -344,14 +345,12 @@
</script>
{% endverbatim %}
<span id="data_api" data-token="{{ token }}" data-instance="{{ instance }}"></span>
<script src="{{ asset('js/jquery.min.js') }}"></script>
<script src="{{ asset('js/jQuery-File-Upload-10.1.0/js/vendor/jquery.ui.widget.js') }}"></script>
<script src="{{ asset('js/jQuery-File-Upload-10.1.0/js/tmpl.min.js') }}"></script>
<script src="{{ asset('js/jQuery-File-Upload-10.1.0/js/load-image.all.min.js') }}"></script>
<script src="{{ asset('js/jQuery-File-Upload-10.1.0/js/canvas-to-blob.min.js') }}"></script>
<script src="{{ asset('js/bootstrap4-toggle.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>
<script src="{{ asset('js/bootstrap-toggle.min.js') }}"></script>
@ -397,6 +396,7 @@
<script src="{{ asset('js/moment.js') }}"></script>
<script src="{{ asset('js/emojionearea.js') }}"></script>
<script type="text/javascript">
$(function() {
'use strict';
@ -422,7 +422,7 @@
' <div class="col-md-4">\n' +
' <img src="'+data.preview_url+'" style="width:100%;max-width:200px;" id="media_preview_'+data.id+'"/>\n' +
' </div>\n' +
' <div class="col-md-6">\n' +
' <div class="col-6">\n' +
' <textarea name="media_description_'+data.id+'" class="form-control"></textarea>\n' +
' </div>\n' +
' <input type="hidden" name="media_id_'+data.id+'" value="'+data.id+'"/>\n' +
@ -480,6 +480,8 @@
if($('#poll_container').hasClass("d-none") ){
$('#poll_container').removeClass("d-none");
$('#compose_attach_poll').val(1);
document.querySelector('#compose_poll_multiple').bootstrapToggle('destroy');
document.querySelector('#compose_poll_multiple').bootstrapToggle();
}else{
$('#poll_container').addClass("d-none");
$('#compose_attach_poll').val(0);
@ -544,14 +546,16 @@
searchPosition: "bottom",
search: false
});
var timezone;
let userTimezone;
if(!!sessionStorage.getItem('timeZone')) {
timezone = sessionStorage.getItem('timeZone');
userTimezone = sessionStorage.getItem('timeZone');
} else {
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
}
$('#compose_timeZone').val(timezone);
$("#compose_scheduled_at").val(new Date(new Date().toString().split('GMT')[0]+' UTC').toISOString().split('.')[0]);
$('#compose_timeZone').val(userTimezone);
$('#compose_timeZone').on('change', function () {
sessionStorage.setItem("timeZone", this.value);
});

View file

@ -4,36 +4,35 @@
{% block content %}
{% include 'nav.html.twig' %}
<h1>{{ 'common.scheduled'|trans }}</h1>
{% set instanceConfiguration = app.session.get("instance").getConfiguration() %}
<h3>{{ 'common.scheduled'|trans }} <span class="border rounded border-light" style="padding-bottom: 5px;padding-left: 5px;padding-right: 5px; margin-right: 5px;"><img width="30" src="{{ app.user.avatar }}" alt="{{ app.user.avatar }}"/> {{ convertAccountEmoji(app.user, app.user.displayName) | raw }} </span><small><span class="badge text-bg-light">@{{ app.user.acct}}@{{ instance }}</span></small></h3>
<div class="row container">
<div class="row container"style="margin-top: 30px;">
<div class="col-md-12" id="content"></div>
</div>
<div class="row container hide" id="loader" style="text-align: center;margin-top: 50px;"><div class="lds-ring"><div></div><div></div><div></div><div></div></div></div>
<div class="row hide" id="no_content" style="margin-top: 50px;">
<div class="col-md-offset-3 col-md-6">
<div class="col-offset-3 col-md-6">
<div class="alert alert-warning" style="font-size: 1.5em;text-align: center;">{{ 'common.no_results_found'|trans }}</div>
</div>
</div>
<div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal fade" id="confirm-delete" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">{{ 'common.confirm_delete'|trans }}</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h1 class="modal-title fs-5" id="myModalLabel">{{ 'common.confirm_delete'|trans }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>{{ 'common.delete_message'|trans }} <b><i class="title"></i></b></p>
<p>{{ 'common.proceed_confirm'|trans }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'common.cancel'|trans }}</button>
<button type="button" class="btn btn-secondary btn-cancel" data-bs-dismiss="modal">{{ 'common.cancel'|trans }}</button>
<button type="button" class="btn btn-danger btn-ok">{{ 'common.delete'|trans }}</button>
</div>
</div>
@ -46,11 +45,26 @@
<script src="{{ asset('bundles/fosjsrouting/js/router.min.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<script type="text/javascript">
let userTimezone;
let lang;
if(!!sessionStorage.getItem('timeZone')) {
userTimezone = sessionStorage.getItem('timeZone');
} else {
userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
}
if (navigator.languages !== undefined) {
lang = navigator.languages[0].slice(0,2);
} else {
lang = navigator.language.slice(0,2);
}
function convertTZ(date) {
return new Intl.DateTimeFormat(lang, { dateStyle: "full" , timeStyle: "long", timeZone: userTimezone}).format(new Date(date + " UTC")).toLocaleString();
}
$(document).ready(function() {
window.max_id = "";
$(window).scroll(function() {
if(($(window).scrollTop() == $(document).height() - $(window).height() )&& max_id != null) {
if(($(window).scrollTop() === $(document).height() - $(window).height() )&& max_id != null) {
loadMore();
}
});
@ -64,8 +78,13 @@
$.get( Routing.generate('load_more', { 'max_id': window.max_id } ))
.done(function(data) {
$("#content").append(data.html);
$(".date-UTC").each(function (index){
$( this ).removeClass("date-UTC").addClass("date-converted");
const dateStr = $(this).text();
$(this).text(convertTZ(dateStr));
});
$('#loader').addClass("d-none");
if( typeof data.html != "undefined" && data.html != "") {
if( typeof data.html != "undefined" && data.html !== "") {
// $("#no_content").addClass("d-none");
}else{
$("#no_content").removeClass("d-none");
@ -86,6 +105,7 @@
.done(function(data) {
$("#message_container_"+id).remove();
$('#confirm-delete').modal('hide');
$('.modal-backdrop').remove();
$modalDiv.modal('hide').removeClass('loading');
})
.fail(function() {

View file

@ -1,65 +1,80 @@
{% trans_default_domain 'fediplan' %}
<header>
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-md navbar-light fixed-top bg-light">
<a class="navbar-brand" href="#">FediPlan</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
{% if not is_granted('ROLE_USER') %}
<li class="nav-item {% if app.request.attributes.get('_route') == 'index' %} active {% endif %}">
<a class="nav-link" href="{{ path('index') }}">{{ 'common.login'|trans }} <span class="sr-only">(current)</span></a>
</li>
{% endif %}
{% if is_granted('ROLE_USER') %}
<li class="nav-item {% if app.request.attributes.get('_route') == 'schedule' %}active {% endif %}">
<a class="nav-link" href="{{ path('schedule') }}">{{ 'common.schedule'|trans }}</a>
</li>
<li class="nav-item {% if app.request.attributes.get('_route') == 'scheduled' %} active {% endif %}">
<a class="nav-link" href="{{ path('scheduled') }}">{{ 'common.scheduled'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ path('logout') }}" tabindex="-1" >{{ 'common.logout'|trans }}</a>
</li>
{% endif %}
<li class="nav-item {% if app.request.attributes.get('_route') == 'about' %} active {% endif %}">
<a class="nav-link" href="{{ path('about') }}" tabindex="-1" >{{ 'common.about'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://fedilab.app/page/donations/" tabindex="-1" >{{ 'common.support_my_work'|trans }}</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
{{ getLanguage(app.request.locale) }}
</a>
<div class="dropdown-menu scrollable-menu">
{% set route = app.request.attributes.get('_route') %}
{% if route == "app_fediplan_about" %}
{% set route = "about" %}
<nav class="navbar fixed-top navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">
<img src="{{ asset('img/FediPlan.png') }}" alt="Logo" width="24" height="24" class="d-inline-block align-text-top"/>
FediPlan
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar" aria-controls="offcanvasNavbar" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar" aria-labelledby="offcanvasNavbarLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasNavbarLabel">
<img src="{{ asset('img/FediPlan.png') }}" alt="Logo" width="24" height="24" class="d-inline-block align-text-top"/>
FediPlan
</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav flex-grow-1 pe-3">
{% if not is_granted('ROLE_USER') %}
<li class="nav-item {% if app.request.attributes.get('_route') == 'index' %} active {% endif %}">
<a class="nav-link" href="{{ path('index') }}">{{ 'common.login'|trans }} <span class="sr-only">(current)</span></a>
</li>
{% endif %}
{% if route | length < 5 %}
{% set route = "index" %}
{% if is_granted('ROLE_USER') %}
<li class="nav-item {% if app.request.attributes.get('_route') == 'schedule' %}active {% endif %}">
<a class="nav-link" href="{{ path('schedule') }}">{{ 'common.schedule'|trans }}</a>
</li>
<li class="nav-item {% if app.request.attributes.get('_route') == 'scheduled' %} active {% endif %}">
<a class="nav-link" href="{{ path('scheduled') }}">{{ 'common.scheduled'|trans }}</a>
</li>
{% endif %}
<a class="dropdown-item" href="{{ path(route, {'_locale':'en' }) }}">English</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'fr' }) }}">Français</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'de' }) }}">Deutsch</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'nl' }) }}">Nederlands</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'ar' }) }}">العربية</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'it' }) }}">Italiano</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'pt-PT' }) }}">Português</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'pt-BR' }) }}">Brasil</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'ca' }) }}">Català</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'ja' }) }}">日本語</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'pl' }) }}">Polski</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'ru' }) }}">Русский</a>
<a class="dropdown-item" href="{{ path(route, {'_locale':'uk' }) }}">Украïна</a>
</div>
</li>
</ul>
<li class="nav-item {% if app.request.attributes.get('_route') == 'about' %} active {% endif %}">
<a class="nav-link" href="{{ path('about') }}" tabindex="-1" >{{ 'common.about'|trans }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://fedilab.app/page/donations/" tabindex="-1" >{{ 'common.support_my_work'|trans }}</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ getLanguage(app.request.locale) }}
</a>
<ul class="dropdown-menu scrollable-menu">
{% set route = app.request.attributes.get('_route') %}
{% if route == "app_fediplan_about" %}
{% set route = "about" %}
{% endif %}
{% if route | length < 5 %}
{% set route = "index" %}
{% endif %}
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'en' }) }}">English</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'fr' }) }}">Français</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'de' }) }}">Deutsch</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'nl' }) }}">Nederlands</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'ar' }) }}">العربية</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'it' }) }}">Italiano</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'pt-PT' }) }}">Português</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'pt-BR' }) }}">Brasil</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'ca' }) }}">Català</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'ja' }) }}">日本語</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'pl' }) }}">Polski</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'ru' }) }}">Русский</a></li>
<li><a class="dropdown-item" href="{{ path(route, {'_locale':'uk' }) }}">Украïна</a></li>
</ul>
</li>
{% if is_granted('ROLE_USER') %}
<li class="nav-item">
<a class="nav-link" href="{{ path('logout') }}" tabindex="-1" >{{ 'common.logout'|trans }}</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
</nav>
</header>

View file

@ -53,7 +53,7 @@ page:
instance: مثيل خادمك
about:
scheduling: يسمح FediPlan للمستخدمين برمجة النشر المُسبَق لرسائل ماستدون و بليروما (بمرفقات الوسائط المتعددة).<br/> يجب أن يكون توقيت النشر على الأقل 5 دقائق في المستقبل. يمكنكم برمجة نشر 300 رسالة على الأكثر في آن واحد. البرمجة اليومية للنشر المُسبَق محصورة في نشر 50 رسالة على أقصى حد في اليوم.
data: 'لا يخزّن FediPlan رسائلكم المبرمَجة أو بيانات الاعتماد الخاصة بكم. بل يستخدم فقط واجهة برمجة التطبيقات لماستدون <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">لبرمجة الرسائل</a>'
data: 'لا يخزّن FediPlan رسائلكم المبرمَجة أو بيانات الاعتماد الخاصة بكم. بل يستخدم فقط واجهة برمجة التطبيقات لماستدون <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">لبرمجة الرسائل</a>'
issues: بإمكانكم الإبلاغ عن المشاكل أو طلب تحسينات على <a href="https://github.com/stom79/FediPlan/issues" target="_blank">غيت هب</a> أو <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:

View file

@ -53,8 +53,8 @@ page:
instance: La teva instància
about:
scheduling: FediPlan permet a l'usuari programar missatges per Mastodon i Pleroma (adjuntant-hi mèdia).<br/> La data programada ha de ser almenys 5 minuts més tard. Es poden programar un màxim de 300 missatges alhora i un màxim de 50 missatges per a un dia concret.
data: 'FediPlan no es guarda els missatges programats ni les teves credencials. Només utilitza l''API de Mastodon per <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">la programació de missatges</a>'
issues: Pots fer constar problemes o demanar millores a <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> o <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan no es guarda els missatges programats ni les teves credencials. Només utilitza l''API de Mastodon per <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">la programació de missatges</a>'
issues: Pots fer constar problemes o demanar millores a <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Advertència sobre el contingut

View file

@ -50,8 +50,8 @@ page:
instance: Deine Instanz
about:
scheduling: FediPlan ermöglicht es den Benutzern, Nachrichten für Mastodon und Pleroma (mit Medienanhängen) zu planen.<br/> Der geplante Termin muss mindestens 5 Minuten in der Zukunft liegen. Es können maximal 300 Nachrichten gleichzeitig geplant werden. Es können nur 50 Nachrichten für einen bestimmten Tag geplant werden.
data: 'FediPlan speichert weder Ihre geplanten Nachrichten noch Ihre Zugangsdaten. Es verwendet die Mastodon API nur für <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">geplante Nachrichten</a>'
issues: Du kannst Probleme melden oder Verbesserungen vorschlagen auf <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> oder <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan speichert weder Ihre geplanten Nachrichten noch Ihre Zugangsdaten. Es verwendet die Mastodon API nur für <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">geplante Nachrichten</a>'
issues: Du kannst Probleme melden oder Verbesserungen vorschlagen auf <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Inhaltshinweis

View file

@ -48,15 +48,15 @@ error:
mastodon_account_already_used: This account is already managed by someone else!
page:
index:
about: FediPlan is an open source application (<a href="https://framagit.org/tom79/fediplan" target="_blank">source code</a>) built for scheduling your messages with <a href="https://joinmastodon.org/" target="_blank">Mastodon</a> or <a href="https://pleroma.social/" target="_blank">Pleroma</a> (2.7+).
about: FediPlan is an open source application (<a href="https://framagit.org/tom79/fediplan" target="_blank">source code</a>) built for scheduling your messages with <a href="https://joinmastodon.org/" target="_blank">Mastodon</a> or <a href="https://pleroma.social/" target="_blank">Pleroma</a> (2.0.7+).
data: It <b>does not store any data</b> (token or messages), that is why you need to create a new Token when your session expired.
form:
code: Your authorization code
instance: Your instance
about:
scheduling: FediPlan allows users to schedule messages for Mastodon and Pleroma (with media attachments).<br/> The scheduled date must be at least 5 minutes into the future. At most, 300 messages can be scheduled at the same time. Only 50 messages can be scheduled for any given day.
data: 'FediPlan does not store your scheduled messages nor your credentials. It only uses the Mastodon API for <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">scheduling messages</a>'
issues: You can report issues or ask improvements on <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> or <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan does not store your scheduled messages nor your credentials. It only uses the Mastodon API for <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">scheduling messages</a>'
issues: You can report issues or ask improvements on <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Content warning

View file

@ -53,8 +53,8 @@ page:
instance: Su instancia
about:
scheduling: FediPlan permite a los usuarios programar mensajes para Mastodon y Pleroma (con archivos multimedia adjuntos).<br/> La fecha programada debe ser de al menos 5 minutos en el futuro. Como máximo, se pueden programar 300 mensajes al mismo tiempo. Solo se pueden programar 50 mensajes para un día determinado.
data: 'FediPlan no almacena tus mensajes programados ni tus credenciales. Solo utiliza la API de Mastodon para <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">programar mensajes</a>'
issues: Puedes reportar problemas o solicitar mejoras en <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> o en<a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan no almacena tus mensajes programados ni tus credenciales. Solo utiliza la API de Mastodon para <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">programar mensajes</a>'
issues: Puedes reportar problemas o solicitar mejoras en <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Advertencia de contenido

View file

@ -53,8 +53,8 @@ page:
instance: Votre instance
about:
scheduling: FediPlan permet aux utilisateur·rice·s de planifier la publication des messages Mastodon et Pleroma (avec médias comme pièces jointes).<br/> La date de planification doit être dau moins 5 minutes à lavance. Vous pouvez planifier jusquà 300 messages à la fois. Seuls 50 messages par jour peuvent être planifiés pour publication.
data: 'FediPlan ne conserve pas vos messages planifiés ni vos identifiants. Il utilise uniquement lAPI de Mastodon pour <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">la planification des messages</a>'
issues: Vous pouvez signaler des problèmes rencontrés ou demander des améliorations sur <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> ou <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan ne conserve pas vos messages planifiés ni vos identifiants. Il utilise uniquement lAPI de Mastodon pour <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">la planification des messages</a>'
issues: Vous pouvez signaler des problèmes rencontrés ou demander des améliorations sur <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Avertissement sur le contenu

View file

@ -55,7 +55,7 @@ page:
instance: インスタンス
about:
scheduling: FediPlanはMastodonとPleromaでメディア付きのメッセージの予約ができます。<br/>予約日時は5分後以降である必要があります。最大で同時に300件のメッセージを予約できます。1日に予約できるメッセージは50件までです。
data: 'FediPlanは予約したメッセージや資格情報を保存しません。<a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">メッセージの予約</a>にはMastodon APIのみを利用します。'
data: 'FediPlanは予約したメッセージや資格情報を保存しません。<a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">メッセージの予約</a>にはMastodon APIのみを利用します。'
issues: <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a>や<a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>で問題の報告や改善の要望ができます。
schedule:
form:

View file

@ -50,8 +50,8 @@ page:
instance: Uw instantie
about:
scheduling: FediPlan stelt gebruikers in staat om berichten te plannen voor Mastodon en Pleroma (met mediabijlagen).<br/> De geplande datum moet ten minste 5 minuten in de toekomst zijn. Er kunnen maximaal 300 berichten op hetzelfde moment worden ingepland. Slechts 50 berichten kunnen worden ingepland voor elke dag.
data: 'FediPlan slaat uw geplande berichten en uw referenties niet op. Het gebruikt alleen de Mastodon API voor <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">berichten planning</a>'
issues: Je kunt problemen melden of verbeteringen aanvragen op <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> of <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan slaat uw geplande berichten en uw referenties niet op. Het gebruikt alleen de Mastodon API voor <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">berichten planning</a>'
issues: Je kunt problemen melden of verbeteringen aanvragen op <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Inhoud waarschuwing

View file

@ -55,7 +55,7 @@ page:
instance: Twoja instancja
about:
scheduling: FediPlan pozwala użytkownikom na planowanie wiadomości na Mastodona i Pleroma (z załącznikami multimedialnymi).<br/> Planowana data musi wynosić co najmniej 5 minut w przyszłości. Można zaplanować maksymalnie 300 wiadomości w tym samym czasie, z czego dziennie może być opublikowane maksymalnie 50.
data: 'FediPlan nie przechowuje Twoich zaplanowanych wiadomości ani danych logowania. Używa tylko Mastodon API do <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">planowania wiadomości</a>'
data: 'FediPlan nie przechowuje Twoich zaplanowanych wiadomości ani danych logowania. Używa tylko Mastodon API do <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">planowania wiadomości</a>'
issues: Możesz zgłaszać problemy lub prosić o ulepszenia na <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> lub <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:

View file

@ -47,8 +47,8 @@ page:
instance: A sua instância
about:
scheduling: FediPlan permite aos usuários agendar mensagens para Mastodon e Pleroma (com anexos de mídia). <br/> A data agendada deve ser de pelo menos 5 minutos no futuro. No máximo, 300 mensagens podem ser agendadas ao mesmo tempo. Apenas 50 mensagens podem ser agendadas para um determinado dia.
data: 'FediPlan não armazena suas mensagens agendadas nem suas credenciais. Ele usa apenas a API Mastodon para <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">agendando mensagens</a>'
issues: Pode relatar problemas ou pedir melhorias em <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> ou <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan não armazena suas mensagens agendadas nem suas credenciais. Ele usa apenas a API Mastodon para <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">agendando mensagens</a>'
issues: Pode relatar problemas ou pedir melhorias em <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Aviso de conteúdo

View file

@ -53,8 +53,8 @@ page:
instance: A sua instância
about:
scheduling: FediPlan permite aos usuários agendar mensagens para Mastodon e Pleroma (com anexos de mídia). <br/> A data agendada deve ser de pelo menos 5 minutos no futuro. No máximo, 300 mensagens podem ser agendadas ao mesmo tempo. Apenas 50 mensagens podem ser agendadas para um determinado dia.
data: 'FediPlan não armazena suas mensagens agendadas nem suas credenciais. Ele usa apenas a API Mastodon para <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">agendando mensagens</a>'
issues: Pode relatar problemas ou pedir melhorias em <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> ou <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan não armazena suas mensagens agendadas nem suas credenciais. Ele usa apenas a API Mastodon para <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">agendando mensagens</a>'
issues: Pode relatar problemas ou pedir melhorias em <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Aviso de conteúdo

View file

@ -52,8 +52,8 @@ page:
code: Ваш код авторизации
instance: Ваша инстанс
about:
data: 'FediPlan не хранит запланированные сообщения и данные вашей учётной записи. Используются только API Mastodon для <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">запланированных сообщений</a>'
issues: Вы можете сообщить об ошибках или запросить улучшения на <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> или <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan не хранит запланированные сообщения и данные вашей учётной записи. Используются только API Mastodon для <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">запланированных сообщений</a>'
issues: Вы можете сообщить об ошибках или запросить улучшения на <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Предупреждение о контенте

View file

@ -54,7 +54,7 @@ page:
instance: Din instans
about:
scheduling: FediPlan tillåter användare att schemalägga meddelanden för Mastodon och Pleroma (med bilagor till media).<br/> Det planerade datumet måste vara minst 5 minuter in i framtiden. Som mest kan 300 meddelanden schemaläggas samtidigt. Endast 50 meddelanden kan schemaläggas för en viss dag.
data: 'FediPlan lagrar inte dina schemalagda meddelanden eller dina uppgifter. Den använder bara Mastodon API för <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">schemaläggning meddelanden</a>'
data: 'FediPlan lagrar inte dina schemalagda meddelanden eller dina uppgifter. Den använder bara Mastodon API för <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">schemaläggning meddelanden</a>'
schedule:
form:
content_warning: Innehållsvarning

View file

@ -55,8 +55,8 @@ page:
instance: Ваш інстанс
about:
scheduling: FediPlan дозволяє користувачам запланувати повідомлення для Mastodon та Plerom (з медійними вкладеннями).<br/> Запланована дата має бути принаймні 5 хвилин на майбутнє. Не більше 300 повідомлень можна запланувати одночасно. Лише 50 повідомлень можна запланувати на вказаний день.
data: 'FediPlan не зберігає заплановані повідомлення або облікові дані. Він використовує тільки Mastodon API для <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">планувальних повідомлень</a>'
issues: Ви можете повідомити про проблеми або запитати покращення на <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> або <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
data: 'FediPlan не зберігає заплановані повідомлення або облікові дані. Він використовує тільки Mastodon API для <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">планувальних повідомлень</a>'
issues: Ви можете повідомити про проблеми або запитати покращення на <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Framagit</a>.
schedule:
form:
content_warning: Попередження про вміст

View file

@ -55,7 +55,7 @@ page:
instance: 你的实例
about:
scheduling: FediPlan允许用户安排的消息乳齿象和Pleroma(与媒体的附件).<br/> 的预定日期必须至少有5分钟的未来。 最多300消息可以被安排在同一时间。 只有50个消息可以计划用于任何给定的一天。
data: 'FediPlan不存储你的计划的消息也不是你的凭据。 它仅使用乳齿象API for <a href="https://docs.joinmastodon.org/api/rest/statuses/#scheduled-status" target="_blank">调度消息</a>'
data: 'FediPlan不存储你的计划的消息也不是你的凭据。 它仅使用乳齿象API for <a href="https://docs.joinmastodon.org/methods/scheduled_statuses/" target="_blank">调度消息</a>'
issues: 您可以在 <a href="https://github.com/stom79/FediPlan/issues" target="_blank">Github</a> 或 <a href="https://framagit.org/tom79/fediplan/issues" target="_blank">Fragmagit</a> 上报告问题或提出改进。
schedule:
form: