├── translations ├── .gitignore └── messages+intl-icu.cs.yaml ├── src ├── Controller │ ├── .gitignore │ ├── MainController.php │ ├── PreferenceController.php │ └── LemmyLinkController.php ├── Exception │ └── UnsupportedFeatureException.php ├── Dto │ ├── ActivityPubItem.php │ └── ParsedName.php ├── Kernel.php └── Service │ ├── TwigExtension.php │ ├── PreferenceManager.php │ ├── PopularInstancesService.php │ ├── NameParser.php │ ├── LinkProvider │ ├── LinkProviderManager.php │ ├── LinkProvider.php │ ├── KbinLinkProvider.php │ └── LemmyLinkProvider.php │ ├── LemmyApiFactory.php │ ├── ActivityPubResolver.php │ ├── WebFingerParser.php │ └── LemmyObjectResolver.php ├── php └── conf.d │ └── php.ini ├── assets ├── controllers.json ├── tsconfig.json ├── app.ts ├── bootstrap.js ├── controllers │ ├── redirect-controller.ts │ ├── generate-link-controller.ts │ └── save-preference-controller.ts └── styles │ └── app.scss ├── doc └── assets │ ├── lemmy-01.png │ └── lemmy-02.png ├── phpstan.neon.dist ├── config ├── routes.yaml ├── packages │ ├── twig.yaml │ ├── debug.yaml │ ├── routing.yaml │ ├── web_profiler.yaml │ ├── translation.yaml │ ├── nyholm_psr7.yaml │ ├── cache.yaml │ ├── framework.yaml │ ├── webpack_encore.yaml │ └── dev │ │ └── monolog.yaml ├── routes │ ├── framework.yaml │ └── web_profiler.yaml ├── preload.php ├── bundles.php └── services.yaml ├── .env.test ├── public └── index.php ├── templates ├── invalid-user.html.twig ├── invalid-community.html.twig ├── redirect.html.twig ├── base.html.twig ├── index.html.twig ├── how-does-it-work.html.twig └── save-instance-preference.html.twig ├── tests ├── bootstrap.php └── Service │ ├── PreferenceManagerTest.php │ └── NameParserTest.php ├── bin ├── console └── phpunit ├── .gitignore ├── .env ├── .github └── workflows │ ├── code-coverage.yml │ ├── tests.yaml │ └── publish.yaml ├── shell.nix ├── LICENSE ├── package.json ├── phpunit.xml.dist ├── webpack.config.js ├── composer.json ├── README.md ├── .php-cs-fixer.dist.php ├── symfony.lock └── serverless.yml /translations/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Controller/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /php/conf.d/php.ini: -------------------------------------------------------------------------------- 1 | extension=intl 2 | -------------------------------------------------------------------------------- /assets/controllers.json: -------------------------------------------------------------------------------- 1 | { 2 | "controllers": [], 3 | "entrypoints": [] 4 | } 5 | -------------------------------------------------------------------------------- /doc/assets/lemmy-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RikudouSage/lemmyverse.link/HEAD/doc/assets/lemmy-01.png -------------------------------------------------------------------------------- /doc/assets/lemmy-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RikudouSage/lemmyverse.link/HEAD/doc/assets/lemmy-02.png -------------------------------------------------------------------------------- /phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: max 3 | symfony: 4 | containerXmlPath: var/cache/dev/App_KernelDevDebugContainer.xml 5 | -------------------------------------------------------------------------------- /config/routes.yaml: -------------------------------------------------------------------------------- 1 | controllers: 2 | resource: 3 | path: ../src/Controller/ 4 | namespace: App\Controller 5 | type: attribute 6 | -------------------------------------------------------------------------------- /assets/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "moduleResolution": "NodeNext", 5 | "module": "NodeNext" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /config/packages/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | default_path: '%kernel.project_dir%/templates' 3 | 4 | when@test: 5 | twig: 6 | strict_variables: true 7 | -------------------------------------------------------------------------------- /config/routes/framework.yaml: -------------------------------------------------------------------------------- 1 | when@dev: 2 | _errors: 3 | resource: '@FrameworkBundle/Resources/config/routing/errors.xml' 4 | prefix: /_error 5 | -------------------------------------------------------------------------------- /src/Exception/UnsupportedFeatureException.php: -------------------------------------------------------------------------------- 1 | 7 | {{ "The link you clicked is invalid because the user cannot be resolved:"|trans }} 8 | {{ user }}. 9 |
10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /assets/app.ts: -------------------------------------------------------------------------------- 1 | import './bootstrap.js'; 2 | /* 3 | * Welcome to your app's main JavaScript file! 4 | * 5 | * We recommend including the built version of this JavaScript file 6 | * (and its CSS file) in your base layout (base.html.twig). 7 | */ 8 | 9 | // any CSS you import will output into a single css file (app.css in this case) 10 | import './styles/app.scss'; 11 | -------------------------------------------------------------------------------- /templates/invalid-community.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block title %}{{ "Error" | trans }}{% endblock %} 4 | 5 | {% block body %} 6 |7 | {{ "The link you clicked is invalid because the community cannot be resolved:"|trans }} 8 | {{ community }}. 9 |
10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /src/Kernel.php: -------------------------------------------------------------------------------- 1 | getProjectDir() . '/var/cache/' . $this->environment; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /config/packages/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | utf8: true 4 | 5 | # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. 6 | # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands 7 | #default_uri: http://localhost 8 | 9 | when@prod: 10 | framework: 11 | router: 12 | strict_requirements: null 13 | -------------------------------------------------------------------------------- /config/packages/web_profiler.yaml: -------------------------------------------------------------------------------- 1 | when@dev: 2 | web_profiler: 3 | toolbar: true 4 | intercept_redirects: false 5 | 6 | framework: 7 | profiler: 8 | only_exceptions: false 9 | collect_serializer_data: true 10 | 11 | when@test: 12 | web_profiler: 13 | toolbar: false 14 | intercept_redirects: false 15 | 16 | framework: 17 | profiler: { collect: false } 18 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | bootEnv(dirname(__DIR__) . '/.env'); 11 | } 12 | 13 | if ($_SERVER['APP_DEBUG']) { 14 | umask(0); 15 | } 16 | -------------------------------------------------------------------------------- /assets/bootstrap.js: -------------------------------------------------------------------------------- 1 | import { startStimulusApp } from '@symfony/stimulus-bridge'; 2 | 3 | // Registers Stimulus controllers from controllers.json and in the controllers/ directory 4 | export const app = startStimulusApp(require.context( 5 | '@symfony/stimulus-bridge/lazy-controller-loader!./controllers', 6 | true, 7 | /\.[jt]sx?$/ 8 | )); 9 | // register any custom, 3rd party controllers here 10 | // app.register('some_controller_name', SomeImportedController); 11 | -------------------------------------------------------------------------------- /src/Service/TwigExtension.php: -------------------------------------------------------------------------------- 1 | urlDecode(...)), 14 | ]; 15 | } 16 | 17 | private function urlDecode(string $text): string 18 | { 19 | return urldecode($text); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/packages/translation.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | default_locale: en 3 | set_locale_from_accept_language: true 4 | set_content_language_from_locale: true 5 | enabled_locales: [en, cs] 6 | translator: 7 | default_path: '%kernel.project_dir%/translations' 8 | fallbacks: 9 | - en 10 | # providers: 11 | # crowdin: 12 | # dsn: '%env(CROWDIN_DSN)%' 13 | # loco: 14 | # dsn: '%env(LOCO_DSN)%' 15 | # lokalise: 16 | # dsn: '%env(LOKALISE_DSN)%' 17 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | requestStack->getCurrentRequest()?->cookies->get($this->cookieName); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /config/bundles.php: -------------------------------------------------------------------------------- 1 | ['all' => true], 5 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], 6 | Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], 7 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], 8 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['dev' => true], 9 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], 10 | Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], 11 | Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], 12 | ]; 13 | -------------------------------------------------------------------------------- /config/packages/nyholm_psr7.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | # Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories) 3 | Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory' 4 | Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory' 5 | Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory' 6 | Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory' 7 | Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory' 8 | Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory' 9 | 10 | nyholm.psr7.psr17_factory: 11 | class: Nyholm\Psr7\Factory\Psr17Factory 12 | -------------------------------------------------------------------------------- /src/Service/PopularInstancesService.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * @todo actually get the list without hardcoding it and remove @codeCoverageIgnore 11 | * 12 | * @codeCoverageIgnore 13 | */ 14 | public function getPopularInstances(): array 15 | { 16 | return [ 17 | 'lemmy.world', 18 | 'lemm.ee', 19 | 'lemmy.ca', 20 | 'beehaw.org', 21 | 'lemmy.dbzer0.com', 22 | 'lemmings.world', 23 | 'lemmy.blahaj.zone', 24 | 'discuss.online', 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /bin/phpunit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [a-zA-Z0-9_-]+)@(?10 | {{ "Redirecting to {link} in {targetStart}{seconds}{targetEnd} seconds..." | trans({ 11 | '{link}': url, 12 | '{seconds}': timeout, 13 | '{targetStart}': '', 14 | '{targetEnd}': '' 15 | }) | raw }} 16 |
17 |18 | 19 | 20 | {{ "Change your instance" | trans }} 21 | 22 | 23 |
24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /templates/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |{{ "Without it being tied to any particular instance." | trans }}
15 | 21 |22 | {{ "Just paste the link in the box above." | trans }} 23 |
24 | 29 | 41 |43 | {{ "How does it work?" | trans }} 45 | 49 | {{ "Configure instance and delay" | trans }} 50 | 51 |
52 |9 | {{ "This service is used for linking to Lemmy communities, users, posts etc. in a universal way." | trans }} 10 | {{ "When you use this service, you give your users the option to view a community or a user profile on their preferred instance instead of going through a complicated process just to interact with the link." | trans }} 11 |
12 |16 | {{ "You are being taken to the '{community}' community. You might configure your home instance so that you are redirected automatically in the future." | trans({ 17 | '{community}': community, 18 | }) }} 19 |
20 | {% elseif user %} 21 |22 | {{ "You are being taken to the '{user}' user profile. You might configure your home instance so that you are redirected automatically in the future." | trans({ 23 | '{user}': user, 24 | }) }} 25 |
26 | {% elseif comment and post %} 27 |28 | {{ "You are being taken to a comment for a post '{post}'. You might configure your home instance so that you are redirected automatically in the future." | trans({ 29 | '{post}': post.name, 30 | }) }} 31 |
32 | {% elseif post %} 33 |34 | {{ "You are being taken to a post '{post}'. You might configure your home instance so that you are redirected automatically in the future." | trans({ 35 | '{post}': post.name, 36 | }) }} 37 |
38 | {% elseif home %} 39 |40 | {{ "Here you can configure your target instance and redirect delay." | trans }} 41 | {{ "Back to homepage" | trans }}. 42 |
43 | {% else %} 44 |45 | {{ "You are being taken to a link on Lemmy. You might configure your home instance so that you are redirected automatically in the future." | trans}} 46 |
47 | {% endif %} 48 | 49 | 60 | 67 |{{ "Your preferred delay (in seconds)" | trans }}:
78 | 84 |