Compare commits

..

266 commits

Author SHA1 Message Date
8310e7fd18 Merge pull request 'atproto: Transmit the correct parcel when fetching missing posts' (#1646) from heluecht/friendica-addons:parcel into develop
Reviewed-on: friendica/friendica-addons#1646
2026-04-11 13:37:01 +02:00
d2e71b0307 atproto: Transmit the correct parcel when fetching missing posts 2026-04-08 10:37:31 +00:00
8328d3b583 Merge pull request 'Invidious Addon Optimization' (#1643) from loma-one/friendica-addons:loma-one-patch-2 into develop
Reviewed-on: friendica/friendica-addons#1643
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2026-04-08 04:13:50 +02:00
f9f767c021 Invidious Addon Optimization
Performance: Consolidated multiple preg_replace calls into a single, efficient regex pass.
Support: Added handling for YouTube Shorts, Music, and Embed links.
Features: Enhanced link detection to preserve video timestamps (?t=...).
Robustness: Improved URL sanitization to prevent broken links (double slashes) and added rel="noopener" for security.
UI: Cleaned up the footer note by displaying a clickable hostname instead of the full URL.
2026-04-08 04:13:50 +02:00
1268d8fc98 Merge pull request 'Mailstream: delete cookiejar after fetching image' (#1645) from mexon/friendica-addons:mat/mailstream-delete-cookiejar into develop
Reviewed-on: friendica/friendica-addons#1645
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2026-04-06 23:11:06 +02:00
Matthew Exon
0820765c4e Mailstream: delete cookiejar after fetching image 2026-04-06 23:11:06 +02:00
a888947b67 Merge pull request 'AT-Protocol: Configurable web frontend' (#1644) from heluecht/friendica-addons:atproto2 into develop
Reviewed-on: friendica/friendica-addons#1644
2026-04-04 08:21:35 +02:00
7ffd587819 AT-Protocol: Configurable web frontend 2026-03-29 13:31:47 +00:00
52f7242247 Merge pull request '"bluesky" is now "AT Protocol"' (#1642) from heluecht/friendica-addons:bluesky into develop
Reviewed-on: friendica/friendica-addons#1642
2026-03-29 11:40:23 +02:00
ea16229e27 Merge branch 'develop' into bluesky 2026-03-29 11:40:08 +02:00
3d199ba7d7 Setting for preferred web front end added 2026-03-18 13:21:21 +00:00
5a099deded Renamed function 2026-03-17 21:30:07 +00:00
d7a380bad5 "bluesky" is now "AT Protocol" 2026-03-15 23:17:04 +00:00
f552fff6b8 Merge pull request 'Add QuickPhoto Addon: Elegant BBCode simplification for images' (#1639) from loma-one/friendica-addons:loma-one-patch-1 into develop
Reviewed-on: friendica/friendica-addons#1639
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2026-03-07 17:20:56 +01:00
2e9f640724 quickphoto/quickphoto.php aktualisiert
DI::l10n()->t inserted
2026-03-07 17:09:57 +01:00
59ece8856c Translation file 2026-03-07 15:13:03 +01:00
aa47cc6e04 quickphoto/quickphoto.js aktualisiert
Make sure the translation is applied.
2026-03-07 15:13:03 +01:00
4a133456ce quickphoto/quickphoto.php aktualisiert
Provides a translation
2026-03-07 15:13:03 +01:00
22026ed533 quickphoto/quickphoto.js aktualisiert
"Description" instead of "Bildbeschreibung"
2026-03-07 15:13:03 +01:00
29e8c2875c quickphoto/README.md aktualisiert
Inserted | in `[img]|filename description[/img]`
2026-03-07 15:13:03 +01:00
0ae86dafa0 quickphoto/README.md hinzugefügt 2026-03-07 15:13:03 +01:00
ec3b0c5941 Add QuickPhoto Addon: Elegant BBCode simplification for images
This PR introduces the QuickPhoto addon, designed to improve the user experience within the Friendica editor. It addresses the issue of long, cluttered BBCodes (monster-links) that appear when images are inserted via drag-and-drop or the image uploader.
Key Features

- Automatic Simplification: Replaces complex [url=...][img=...]...[/img][/url] structures with a human-readable shorthand: [img]filename|description[/img].
- Seamless Reconstruction: Automatically restores the full, valid Friendica BBCode before previewing or submitting a post, ensuring 100% compatibility with the server.
- Enhanced Readability: Keeps the editor clean and focus-oriented while writing long posts with multiple images.

Technical Highlights & Optimizations

- Resource Efficient: The JavaScript is strictly scoped. It only becomes active if a textarea is present and visible in the DOM.
- Zero Latency Typing: Implements requestIdleCallback and throttling (500ms) to ensure that the simplification process never interferes with the user's typing flow or causes UI lag.
- Background Throttling: Logic is suspended when the browser tab is inactive (document.hidden) to save CPU and battery life.
- LocalStorage Cache: Uses a local cache for image data (auto-cleaned after 12 hours) to ensure reliability during a single editing session.

Testing performed

- Tested with the standard "Jot" editor and the newer Compose/Comment templates.
- Verified that image previews render correctly (reconstruction triggers on preview click).
- Verified that the final post contains the correct full BBCode on the server side.
- Confirmed that Drag & Drop inserts are handled immediately.
2026-03-07 15:13:03 +01:00
3509144228 Add QuickPhoto Addon: Elegant BBCode simplification for images
This PR introduces the QuickPhoto addon, designed to improve the user experience within the Friendica editor. It addresses the issue of long, cluttered BBCodes (monster-links) that appear when images are inserted via drag-and-drop or the image uploader.
Key Features

- Automatic Simplification: Replaces complex [url=...][img=...]...[/img][/url] structures with a human-readable shorthand: [img]filename|description[/img].
- Seamless Reconstruction: Automatically restores the full, valid Friendica BBCode before previewing or submitting a post, ensuring 100% compatibility with the server.
- Enhanced Readability: Keeps the editor clean and focus-oriented while writing long posts with multiple images.

Technical Highlights & Optimizations

- Resource Efficient: The JavaScript is strictly scoped. It only becomes active if a textarea is present and visible in the DOM.
- Zero Latency Typing: Implements requestIdleCallback and throttling (500ms) to ensure that the simplification process never interferes with the user's typing flow or causes UI lag.
- Background Throttling: Logic is suspended when the browser tab is inactive (document.hidden) to save CPU and battery life.
- LocalStorage Cache: Uses a local cache for image data (auto-cleaned after 12 hours) to ensure reliability during a single editing session.

Testing performed

- Tested with the standard "Jot" editor and the newer Compose/Comment templates.
- Verified that image previews render correctly (reconstruction triggers on preview click).
- Verified that the final post contains the correct full BBCode on the server side.
- Confirmed that Drag & Drop inserts are handled immediately.
2026-03-07 15:13:03 +01:00
ade3c6b22e Merge pull request 'IRC: Use friendica nickname as suggested IRC nickname, when signed in' (#1637) from marcusxs/friendica-addons:default_irc_nickname_to_friendica_nickname into develop
Reviewed-on: friendica/friendica-addons#1637
2026-03-07 15:07:09 +01:00
Marcus F.
31c130436c IRC: Use friendica nickname as suggested IRC nickname, when signed in 2026-03-07 13:31:50 +01:00
8a4715271c Merge pull request 'Mailstream: respect blocked/ignored/collapsed contact settings' (#1640) from mexon/friendica-addons:mat/mailstream-block into develop
Reviewed-on: friendica/friendica-addons#1640
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2026-03-07 04:12:30 +01:00
Matthew Exon
ed70b2ca27 Mailstream: respect blocked/ignored/collapsed contact settings 2026-03-02 18:13:28 +01:00
2c75b00b16 Merge pull request 'Smileybutton Add-on Upgrade (github PR 1380)' (#1638) from tobias/friendica-addons:rp-smileybutton into develop
Reviewed-on: friendica/friendica-addons#1638
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2026-02-13 16:56:19 +01:00
Random Penguin
6d3dd9b8b2 Update smileybutton.php
- Enabling for Quattro. Enabled for Mobile because it may have emoji mobile devices do not have. Switched structure from <table> to <div> to make layout more flexible.
- Switched to DIV layout
- Also fixes button and position appearance.
- Also fixes button alignment and appearance issues
- Adding support for Quattro theme
2026-02-10 21:22:03 -05:00
cfbc6676f0 merged stable into develop 2026-01-27 08:40:49 +01:00
62e71da0d7 Merge branch '2025.07-rc' into stable 2026-01-27 08:31:23 +01:00
d8673f9011 Merge pull request 'audon/audon.php aktualisiert' (#1631) from loma-one/friendica-addons:2025.07-rc into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1631
2026-01-18 19:00:47 +01:00
e95dd66b2b audon/audon.php aktualisiert
The Audon project has been discontinued.
2026-01-18 19:00:47 +01:00
ce97294546 Merge pull request 'Update markdown translations for da-dk' (#1636) from marcusxs/friendica-addons:update_markdown_da_dk_translations into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1636
2026-01-18 18:55:38 +01:00
Marcus F.
d2123c9b87 Update markdown translations for da-dk 2026-01-18 15:01:55 +01:00
eb8255c40d Merge pull request 'updated translations' (#1635) from tobias/friendica-addons:20260108-lng into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1635
2026-01-11 18:59:10 +01:00
b4fdbdcadc updated translations 2026-01-08 09:43:41 +01:00
fb0816eb39 Merge pull request 'New converse.js based XMPP addon' (#1621) from heluecht/friendica-addons:xmpp-converse into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1621
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-12-16 16:02:57 +01:00
f31047f3c8 XMPP addon is created 2025-12-16 16:02:57 +01:00
51c0b11287 Merge pull request 'Fix PHPStan error' (#1625) from heluecht/friendica-addons:phpstan into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1625
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-12-16 15:58:54 +01:00
b060be281f Fix PHPStan error 2025-12-16 15:58:54 +01:00
ff7025d852 Merge pull request 'Add references header for more robust threading in mail clients' (#1624) from mexon/friendica-addons:mat/mailstream-references into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1624
2025-12-14 12:02:18 +01:00
Matthew Exon
cfc7193122 Add references header for more robust threading in mail clients 2025-12-13 11:29:59 +01:00
0bf1d3eec9 Merge pull request 'Increased speed for "follow" requests' (#1622) from heluecht/friendica-addons:follow-speed into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1622
2025-12-01 18:09:41 +01:00
53ca699b16 Increased speed for "follow" requests 2025-12-01 18:09:41 +01:00
cf8c798c76 Merge pull request 'tesseract/tesseract.php aktualisiert' (#1609) from loma-one/friendica-addons:develop into develop
Reviewed-on: friendica/friendica-addons#1609
2025-12-01 18:08:39 +01:00
324bc97c52 tesseract/tesseract.php aktualisiert
Modified addon.
The addon used to generate a large system load and led to the server being unavailable. The changes help to make better use of system resources.

- Creates and removes tesseract-limited.sh to limit the system resources for tesseract (timeout/resource limits).
- Checks permitted formats to avoid wasting resources.
2025-12-01 18:08:39 +01:00
633c6799d8 Merge pull request '[CI] Add All-In-One Archive' (#1616) from nupplaPhil/friendica-addons:ci/full-archive into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1616
2025-11-21 23:51:36 +01:00
d47e20b0d4 Enable CI Pipeline 2025-11-21 23:51:36 +01:00
38dcc81d3c Merge pull request 'GitHub Issue 14872: Change Ratioed default sort order' (#1619) from haheute/friendica-addons:ratioed-sort-order into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1619
2025-11-21 23:49:43 +01:00
1fdc6d9794 GitHub Issue 14872: Change Ratioed default sort order 2025-11-20 15:46:44 +01:00
9b3278ffd9 Merge pull request 'add messages.po file for ratioed addon' (#1618) from mexon/friendica-addons:mat/ratioed-translation into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1618
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-11-12 14:36:34 +01:00
Matthew Exon
427f39ad57 add messages.po file for ratioed addon 2025-11-10 07:26:04 +01:00
0562623117 Merge pull request 'Update Link to Transifex Friendica page' (#1617) from haheute/friendica-addons:update-transifex-url into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1617
2025-11-09 19:57:26 +01:00
8d42f99aff Update Link to Transifex Friendica page 2025-11-08 12:34:47 +01:00
6a342088a5 Merge pull request 'Avoid sending group posts through connectors' (#1615) from heluecht/friendica-addons:no-group-posts into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1615
2025-09-14 18:07:56 +02:00
6dcf3cbf5c Avoid sending group posts through connectors 2025-09-01 01:45:44 +00:00
28fcccd9d5 Merge pull request 'Fix several warnings' (#1613) from heluecht/friendica-addons:warnings into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1613
2025-08-07 21:08:38 +02:00
1cc54a83a9 Fix several warnings 2025-08-04 20:48:06 +00:00
e76575eb52 Merge pull request 'Issue 15048: Support addon filters via API' (#1612) from heluecht/friendica-addons:issue-15048 into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1612
2025-07-30 22:40:55 +02:00
b39ab36cee Issue 15048: Support addon filters via API 2025-07-29 21:23:57 +00:00
ea41e2f1b6 Merge pull request 'update PHPMailer' (#1611) from 20250710-phpmailer into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1611
2025-07-23 23:09:06 +02:00
9387db358c update PHPMailer 2025-07-10 06:30:21 +02:00
715f700323 Merge pull request '[Fix] reset Dice calls for LoggerFactory' (#1610) from Art4/friendica-addons:fix-monolog-addon into 2025.07-rc
Reviewed-on: friendica/friendica-addons#1610
2025-07-08 07:10:24 +02:00
Art4
8a8639b07e reset Dice calls for LoggerFactory 2025-06-05 07:56:53 +00:00
97b09d34e9 Merge pull request 'Issue 14667: Pinned Bluesky feeds are fetched again' (#1605) from heluecht/friendica-addons:bluesky-pinned into develop
Reviewed-on: friendica/friendica-addons#1605
2025-05-03 22:02:16 +02:00
2289fdc97e Issue 14667: Pinned Bluesky feeds are fetched again 2025-05-03 22:02:16 +02:00
d95137ce6b Merge pull request 'Bluesky: Support for mentions' (#1606) from heluecht/friendica-addons:bluesky-mentions into develop
Reviewed-on: friendica/friendica-addons#1606
2025-05-03 22:01:06 +02:00
cd4f102d02 Bluesky: Support for mentions 2025-05-03 22:01:06 +02:00
4daaf17110 Merge pull request 'Replace Addon class with AddonHelper' (#1607) from Art4/friendica-addons:replace-addon-class-with-addonhelper into develop
Reviewed-on: friendica/friendica-addons#1607
2025-05-03 21:59:14 +02:00
Art4
48ff761bdb Replace Addon class with AddonHelper 2025-04-28 13:01:41 +00:00
45d3a6fb74 Merge pull request '[CI] Bump PHP versions in woodpecker' (#1604) from nupplaPhil/friendica-addons:feat/woodpecker into develop
Reviewed-on: friendica/friendica-addons#1604
2025-04-27 02:18:37 +02:00
97a3b5815b [CI] Bump PHP versions in woodpecker 2025-04-27 02:18:37 +02:00
95a9f7038a Merge pull request 'PHPStan level 3' (#1603) from Art4/friendica-addons:phpstan-level-3 into develop
Reviewed-on: friendica/friendica-addons#1603
2025-04-27 02:17:41 +02:00
Art4
06b4f164f5 cast db stmt object to array 2025-03-14 08:21:08 +00:00
Art4
38a8e9a169 remove obvious type cast 2025-03-14 08:15:02 +00:00
Art4
db875bc755 Remove type casting to int 2025-03-14 07:49:20 +00:00
Art4
dd58b000d9 Fix error in bluesky addon 2025-03-13 11:57:28 +00:00
Art4
cdeaa433a1 Fix error in diaspora addon 2025-03-13 11:55:34 +00:00
Art4
ad31685237 Fix error in js_upload addon 2025-03-13 11:51:53 +00:00
Art4
2667b4d78e Fix error in libravatar addon 2025-03-13 11:38:18 +00:00
Art4
c56ec7c7c4 Fix error in mailstream addon 2025-03-13 10:29:47 +00:00
Art4
417a3a8198 Fix error in membersince addon 2025-03-13 09:49:18 +00:00
Art4
dda6710b10 Fix error in notifyall addon 2025-03-13 09:36:34 +00:00
Art4
21a7529a0e fix PHPStan error in phpmailer addon 2025-02-26 15:21:19 +00:00
Art4
bbce8c345f Fix PHPStan errors in phpnut addon 2025-02-26 15:12:25 +00:00
Art4
512ad63dbf Fix PHPStan errors in statusnet addon 2025-02-26 14:35:00 +00:00
Art4
cfe27582ee Fix PHPStan error in tumblr addon 2025-02-26 08:47:06 +00:00
Art4
d488c1907a Fix PHPStan error in webdav_storage addon 2025-02-25 15:24:00 +00:00
81b4d3cab4 Merge pull request '[tumblr] Skip empty tags when saving user-defined tags' (#1602) from MrPetovan/friendica-addons:bug/fatal-errors into develop
Reviewed-on: friendica/friendica-addons#1602
2025-02-24 19:23:47 +01:00
ec718ea294 [tumblr] Skip empty tags when saving user-defined tags
- Skip empty tags when fetching them
↪ Empty tags were triggering a Tumblr API error
- Address https://github.com/friendica/friendica/issues/14646#issuecomment-2628090487
- Using log output from https://github.com/friendica/friendica/issues/14646#issuecomment-2665000962
2025-02-20 23:03:27 -05:00
8411a0f5ed Merge pull request 'Improve accessibility with showmore and rendertime' (#1600) from heluecht/friendica-addons:accessibility into develop
Reviewed-on: friendica/friendica-addons#1600
2025-02-16 11:05:52 +01:00
859d92ab02 Improve accessibility with showmore and rendertime 2025-02-16 11:05:52 +01:00
73d4bed31c Merge pull request 'Bluesky: Avoid duplicated reshares' (#1601) from heluecht/friendica-addons:double-reshare into develop
Reviewed-on: friendica/friendica-addons#1601
2025-02-16 11:05:18 +01:00
07008af9c1 Bluesky: Avoid duplicated reshares 2025-02-16 06:12:49 +00:00
0fb2c05244 Merge pull request '[tumblr] Ward against unexpected response format in tumblr_fetch_tags()' (#1599) from MrPetovan/friendica-addons:bug/fatal-errors into develop
Reviewed-on: friendica/friendica-addons#1599
2025-02-08 16:57:13 +01:00
373c30b5d0 [tumblr] Ward against unexpected response format in tumblr_fetch_tags()
- Adress https://github.com/friendica/friendica/issues/14646#issuecomment-2628090487
2025-02-08 16:57:13 +01:00
4454ce5883 Merge pull request 'Implement monolog addon as LoggerFactory' (#1598) from Art4/friendica-addons:loggerfactory-in-monolog-addon into develop
Reviewed-on: friendica/friendica-addons#1598
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-02-08 04:16:47 +01:00
Art4
5701853d29 Remove config docs, format syntax 2025-02-06 11:35:10 +00:00
Art4
ed75360eb4 Setting the logger_config config is no longer needed 2025-02-06 09:27:22 +00:00
Art4
c4f8c65817 Remove wrong phpdoc 2025-02-05 15:32:24 +00:00
Art4
f7ec934893 bump version to 1.1 2025-02-05 15:20:22 +00:00
Art4
0bafcc78f8 Add READMD.md for monolog addon 2025-02-05 15:20:06 +00:00
Art4
e6d92cc94a Rewrite Monolog factory to implement LoggerFactory 2025-02-05 15:11:14 +00:00
16a8172c37 Merge pull request 'Accessibility: Use different id values for options' (#1597) from heluecht/friendica-addons:accessibility into develop
Reviewed-on: friendica/friendica-addons#1597
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-28 23:09:04 +01:00
16127854dd Accessibility: Use different id values for options 2025-01-28 20:27:52 +00:00
7e1bcbdedb Merge pull request 'Add additional theme-filter for disabling/enabling divs.' (#1596) from jakob/friendica-addons:fix-saml-display-settings into develop
Reviewed-on: friendica/friendica-addons#1596
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-25 14:06:07 +01:00
Jakobus Schürz
8384b74696 add condition for selected theme 2025-01-25 08:05:32 -05:00
c5e3d1f047 Merge pull request 'Issue 14692: Avoid loop situation' (#1595) from heluecht/friendica-addons:issue-14692 into develop
Reviewed-on: friendica/friendica-addons#1595
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-25 13:59:52 +01:00
cbfcfb3349 Issue 14692: Avoid loop situation 2025-01-25 02:44:54 +00:00
cdba300c7b Merge pull request 'Replace Logger class with DI::logger()' (#1594) from Art4/friendica-addons:replace-logger-with-loggerinterface into develop
Reviewed-on: friendica/friendica-addons#1594
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-24 14:34:43 +01:00
Art4
4c8c262b07 fix in googlemaps addon 2025-01-24 12:10:58 +00:00
Art4
dd775645d4 Replace call for Logger with DI::logger() in wppost addon 2025-01-24 11:58:32 +00:00
Art4
e4d14cab62 Replace call for Logger with DI::logger() in twitter addon 2025-01-24 11:58:10 +00:00
Art4
a7b26f6453 Replace call for Logger with DI::logger() in tesseract addon 2025-01-24 11:57:34 +00:00
Art4
763c5026f2 Replace call for Logger with DI::logger() in tumblr addon 2025-01-24 11:57:12 +00:00
Art4
bfdccb451c Replace call for Logger with DI::logger() in statusnet addon 2025-01-24 11:56:45 +00:00
Art4
ac6c1d7a49 Replace call for Logger with DI::logger() in saml addon 2025-01-24 11:56:29 +00:00
Art4
32a3160445 Replace call for Logger with DI::logger() in randplace addon 2025-01-24 11:56:09 +00:00
Art4
d50650b8cf Replace call for Logger with DI::logger() in pumpio addon 2025-01-24 11:55:13 +00:00
Art4
e32ba1ce7b Replace call for Logger with DI::logger() in public_server addon 2025-01-24 11:54:34 +00:00
Art4
119ba0a78e Replace call for Logger with DI::logger() in pnut addon 2025-01-24 11:48:21 +00:00
Art4
469d3e6d61 Replace call for Logger with DI::logger() in planets addon 2025-01-24 11:47:40 +00:00
Art4
757d72c360 Replace call for Logger with DI::logger() in openstreetmap addon 2025-01-24 11:47:24 +00:00
Art4
9ceff8f592 Replace call for Logger with DI::logger() in nominatim addon 2025-01-24 11:46:58 +00:00
Art4
9a91bae363 Replace call for Logger with DI::logger() in mailstream addon 2025-01-24 11:46:30 +00:00
Art4
9ed02034f1 Replace call for Logger with DI::logger() in ljpost addon 2025-01-24 11:46:04 +00:00
Art4
f08750199d Replace call for Logger with DI::logger() in libertree addon 2025-01-24 11:45:25 +00:00
Art4
a488f25131 Replace call for Logger with DI::logger() in ldapauth addon 2025-01-24 11:44:48 +00:00
Art4
5d51c5b56e Replace call for Logger with DI::logger() in js_upload addon 2025-01-24 11:42:25 +00:00
Art4
5002318089 Replace call for Logger with DI::logger() in ijpost addon 2025-01-24 11:41:02 +00:00
Art4
15a951235f Replace call for Logger with DI::logger() in ifttt addon 2025-01-24 11:40:32 +00:00
Art4
e7755584cb Replace call for Logger with DI::logger() in geocoordinates addon 2025-01-24 11:40:12 +00:00
Art4
1db552ead9 Replace call for Logger with DI::logger() in dwpost addon 2025-01-24 11:39:11 +00:00
Art4
b38c2d18be Replace call for Logger with DI::logger() in discourse addon 2025-01-24 11:38:48 +00:00
Art4
4881e6004a Replace call for Logger with DI::logger() in diaspora addon 2025-01-24 11:38:27 +00:00
Art4
1d1a00df27 Replace call for Logger with DI::logger() in cld addon 2025-01-24 11:37:58 +00:00
Art4
77ebaca281 Replace call for Logger with DI::logger() in ratioed addon 2025-01-24 11:37:28 +00:00
Art4
d78ea50516 Replace call for Logger with DI::logger() in bluesky addon 2025-01-24 11:36:23 +00:00
Art4
41f280f0c7 Replace call for Logger with DI::logger() in blockbot addon 2025-01-24 11:34:33 +00:00
Art4
4310c1355d Replace call for Logger with DI::logger() 2025-01-24 10:53:01 +00:00
1cc5a6688e Merge pull request 'rework saml addon' (#1588) from jakob/friendica-addons:fix-saml-display-settings into develop
Reviewed-on: friendica/friendica-addons#1588
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-23 14:31:49 +01:00
Jakobus Schürz
0b4aaac9fd translation for saml-hint 2025-01-23 14:31:49 +01:00
Jakobus Schürz
c506367273 replace password-handling with hint
also add hint to email-field
2025-01-23 14:31:49 +01:00
Jakobus Schürz
792f50f835 fix view in vier and frio 2025-01-23 14:31:49 +01:00
Jakobus Schürz
2b5764c132 rework saml addon
fix #1587
remove css-side hiding of elements, which was broken.
remove them or make them readonly via javascript
2025-01-23 14:31:49 +01:00
69e75ef88b Merge pull request 'Check PHPStan in addons' (#1592) from Art4/friendica-addons:fix-phpstan-error into develop
Reviewed-on: friendica/friendica-addons#1592
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-23 14:29:59 +01:00
Art4
7a7940a8ed Fix PHPStan errors 2025-01-23 08:29:13 -05:00
Art4
2741227bfa Add phpstan in woodpacker 2025-01-23 08:27:48 -05:00
13cffd76db Merge pull request 'Clean up phpstan warning' (#1591) from mexon/friendica-addons:mat/ratioed-fix-warning into develop
Reviewed-on: friendica/friendica-addons#1591
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2025-01-23 14:26:41 +01:00
Matthew Exon
0d0aae36cd Clean up phpstan warning 2025-01-23 08:26:23 -05:00
28d3041694 Merge pull request 'Fix codestyle' (#1590) from heluecht/friendica-addons:ratiod-fix into develop
Reviewed-on: friendica/friendica-addons#1590
2025-01-22 08:49:57 +01:00
cb70a4eaff Fix codestyle 2025-01-18 15:25:50 +00:00
0c96d0f4bb Merge pull request 'Ratioed: add statistics about reply likes and reply guy score' (#1589) from mexon/friendica-addons:mat/reply-guy-score into develop
Reviewed-on: friendica/friendica-addons#1589
2025-01-16 06:43:41 +01:00
Matthew Exon
ee8c852d38 Ratioed: remove action buttons 2025-01-15 19:33:11 +01:00
Matthew Exon
807598dbd0 Ratioed: wrap long lines 2025-01-15 19:32:55 +01:00
Matthew Exon
8ba4cd5f61 Ratioed: bump version number 2025-01-12 14:33:21 +01:00
Matthew Exon
3441c9bd0e Ratioed: add statistics about reply likes and reply guy score 2025-01-12 14:33:21 +01:00
44d2079da2 Merge pull request 'Ratioed: several fixes to functionality' (#1586) from mexon/friendica-addons:mat/ratioed-fixes into develop
Reviewed-on: friendica/friendica-addons#1586
2025-01-12 12:03:00 +01:00
Matthew Exon
b360b553ed Ratioed: remove actions 2025-01-12 12:03:00 +01:00
Matthew Exon
46b3836720 Ratioed: remove create user button 2025-01-12 12:03:00 +01:00
Matthew Exon
81639ff615 Ratioed: fix sorting by columns 2025-01-12 12:03:00 +01:00
Matthew Exon
d495810b2d Ratioed: allow both sorting directions 2025-01-12 12:03:00 +01:00
Matthew Exon
2ef9cb8add Ratioed: fill in zeroes for empty values 2025-01-12 12:03:00 +01:00
Matthew Exon
8e65141cb5 Ratioed: bump version number 2025-01-12 12:03:00 +01:00
Matthew Exon
d034e311cb Ratioed: add help link 2025-01-12 12:03:00 +01:00
db10da2f02 Merge pull request '[CI] Fix releaser' (#1585) from nupplaPhil/friendica-addons:ci/stable_pick into develop
Reviewed-on: friendica/friendica-addons#1585
2025-01-02 08:37:19 +01:00
995e81e951
[CI] Fix releaser 2025-01-01 20:22:42 +01:00
f0999a1e46
[CI] Fix releaser 2025-01-01 20:06:43 +01:00
cb2ab0684e Merge branch 'stable' into develop 2024-12-31 18:57:15 +01:00
3b079aef8d Merge pull request 'Bluesky: Preparation to be able to fetch AT links' (#1584) from heluecht/friendica-addons:bluesky-fetch-uri into 2024.09-rc
Reviewed-on: friendica/friendica-addons#1584
2024-12-28 22:23:22 +01:00
9e1f7dc468 Bluesky: Preparation to be able to fetch AT links 2024-12-28 22:23:22 +01:00
Art4
5f557ed0ab Merge branch '2024.09-rc' into merge-2024.09-rc-into-develop 2024-12-23 10:15:53 +00:00
7172695705 Merge pull request '[CI] Fix codecov' (#1583) from nupplaPhil/friendica-addons:bug/ci into 2024.09-rc
Reviewed-on: friendica/friendica-addons#1583
2024-12-23 07:19:43 +01:00
5f50fd2498
Fix codecov token env 2024-12-22 08:54:51 +01:00
0697f078f1
[CI] Fix codecov 2024-12-22 08:38:17 +01:00
f2a9eb151d Merge pull request 'Small bug fix' (#1566) from loma-one/friendica-addons:2024.09-rc into 2024.09-rc
Reviewed-on: friendica/friendica-addons#1566
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2024-12-21 21:57:57 +01:00
16e06f9b2b Small bug fix
Close the Uni-Code Smilies link with a ’;’
2024-12-21 15:56:34 -05:00
a63fb08525 Merge remote-tracking branch '2024.09-rc' into develop
# Conflicts:
#	bluesky/bluesky.php
2024-12-16 09:12:09 -05:00
6cf388f141 Merge remote-tracking branch 'Art4/remove-app-usage' into develop 2024-12-16 09:04:45 -05:00
Art4
c4bea164c7 Merge branch 'develop' into remove-app-usage 2024-12-15 15:55:54 +00:00
04c402607b Merge branch 'Art4/fix-phpstan-error-level-2' into develop 2024-12-15 09:18:47 -05:00
Artur Weigandt
68ee5260b0
Merge branch 'develop' into fix-phpstan-error-level-2 2024-12-13 10:28:15 +01:00
81a84fb895 Merge pull request 'fix-phpstan-error-level-1' (#1579) from MrPetovan/friendica-addons:fix-phpstan-error-level-1 into develop
Reviewed-on: friendica/friendica-addons#1579
2024-12-12 22:37:42 +01:00
Artur Weigandt
729b6e5210 Update mailstream/phpmailer/class.phpmailer.php
Co-authored-by: Hypolite Petovan <hypolite@mrpetovan.com>
2024-12-12 22:37:42 +01:00
Art4
a71db771d9 Fix errors in wppost addon 2024-12-12 22:37:42 +01:00
Art4
2f89827dea fix errors in tictac addon 2024-12-12 22:37:42 +01:00
Art4
8e778593ca fix errors in statusnet addon 2024-12-12 22:37:42 +01:00
Art4
5b623c8368 fix errors in ratioed addon 2024-12-12 22:37:42 +01:00
Art4
bda683c56b fix errors in pumpio addon 2024-12-12 22:37:42 +01:00
Art4
7fa2dfc608 Fix errors in pnut addon 2024-12-12 22:37:42 +01:00
Art4
c0971779c6 Fix errors in nsfw addon 2024-12-12 22:37:42 +01:00
Art4
6b1b043dd8 fix errors in mailstream addon 2024-12-12 22:37:42 +01:00
Art4
984e7c5e5d Fix errors in ljpost addon 2024-12-12 22:37:42 +01:00
Art4
d08a280ba6 Fix errors in libravatar addon 2024-12-12 22:37:42 +01:00
Art4
ee1a917612 Fix errors in leistungsschutzrecht addon 2024-12-12 22:37:42 +01:00
Art4
a53d5ae29b Fix errors in langfilter addon 2024-12-12 22:37:42 +01:00
Art4
3cf53a334d Fix errors in keycloakpassword addon 2024-12-12 22:37:42 +01:00
Art4
81f232d57e Fix errors in js_upload addon 2024-12-12 22:37:42 +01:00
Art4
1860e732ae Fix errors in convert addon 2024-12-12 22:37:42 +01:00
Art4
cf8a7870f3 Fix errors in bluesky addon 2024-12-12 22:37:42 +01:00
Art4
31198294c7 Fix error in bluesky addon 2024-12-12 22:37:42 +01:00
Art4
84659fc1ad Replace DI::app() with DI::appHelper() 2024-12-11 21:47:10 +00:00
Art4
5f7482d081 Remove unused use statements for App 2024-12-11 21:42:48 +00:00
Art4
fff140ad43 Fix last 3 errors 2024-12-09 23:08:31 +00:00
Art4
cfb6b3123f Fix errors in statusnet addon 2024-12-08 23:06:51 +00:00
Art4
b99ac65c0b Fix errors in membersince addon 2024-12-08 22:49:23 +00:00
Art4
89a673cc11 Fix typo 2024-12-08 22:19:58 +00:00
Art4
2fe37c6d4a Fix errors in pnut addon 2024-12-08 21:24:03 +00:00
Art4
5b13274bed Fix class name collision 2024-12-08 21:02:07 +00:00
Art4
82ed43f507 Fix errors 2024-12-07 22:08:59 +00:00
Art4
43c71412e4 Merge branch 'develop' into fix-phpstan-error-level-1 2024-12-01 07:41:27 +00:00
fb9c10f8c5 Merge pull request 'Fix phpstan error level 0 part2' (#1577) from fix-phpstan-error-level-0-part2 into develop
Reviewed-on: friendica/friendica-addons#1577
Reviewed-by: Hypolite Petovan <hypolite@mrpetovan.com>
2024-12-01 03:20:18 +01:00
Art4
1e68417278 Fix classes in s3_storage addon 2024-12-01 03:20:18 +01:00
Art4
7d02c9b53c Fix errors in pumpio addon 2024-12-01 03:20:18 +01:00
Art4
b5c647bd5d fix errors in pnut addon, add support for PHP 7.4 2024-12-01 03:20:18 +01:00
Art4
1bd7cd6e71 fix error in PHPMailer 2024-12-01 03:20:18 +01:00
Art4
def43f3167 Fix errors in mailstream addon 2024-12-01 03:20:18 +01:00
Art4
b661448344 Fix errors in libravatar addon 2024-12-01 03:20:18 +01:00
Art4
922bace555 Fix errors in diaspora addon 2024-12-01 03:20:18 +01:00
Art4
4a2fc7884c remove wrong return tag 2024-12-01 03:20:18 +01:00
Art4
9d172b7082 refactor convert addon, replace each() calls with foreach loop 2024-12-01 03:20:18 +01:00
Art4
4527df602f Add checks for CLD2Detector ans CLD2Encoding classes 2024-12-01 03:20:18 +01:00
Art4
15c21cebb1 Fix errors in wppost addon 2024-11-30 20:36:58 +00:00
Art4
b6a47699bf fix errors in tictac addon 2024-11-30 20:36:07 +00:00
Art4
a41f8c13fe fix errors in statusnet addon 2024-11-30 20:27:57 +00:00
Art4
fccf361ef1 fix errors in ratioed addon 2024-11-30 20:13:41 +00:00
Art4
43ee267d38 fix errors in pumpio addon 2024-11-30 20:12:23 +00:00
Art4
3f89aa1806 Fix errors in pnut addon 2024-11-30 19:51:18 +00:00
Art4
50912fdc17 Fix errors in nsfw addon 2024-11-30 19:50:06 +00:00
Art4
c04016b7d3 fix errors in mailstream addon 2024-11-30 19:48:49 +00:00
Art4
5f6f374f09 Fix errors in ljpost addon 2024-11-30 19:42:40 +00:00
Art4
e86d15993b Fix errors in libravatar addon 2024-11-30 19:41:11 +00:00
Art4
ace19814d7 Fix errors in leistungsschutzrecht addon 2024-11-30 19:37:58 +00:00
Art4
fcec1a3d83 Fix errors in langfilter addon 2024-11-30 19:35:19 +00:00
Art4
04afbe36e3 Fix errors in keycloakpassword addon 2024-11-30 19:32:07 +00:00
Art4
07993f7098 Fix errors in js_upload addon 2024-11-30 19:30:39 +00:00
Art4
bee780552d Fix errors in convert addon 2024-11-30 19:28:38 +00:00
Art4
5664bc84fb Fix errors in bluesky addon 2024-11-30 19:27:50 +00:00
Art4
7246f3deda Merge branch 'fix-phpstan-error-level-0-part2' into fix-phpstan-error-level-1 2024-11-30 19:23:00 +00:00
Art4
0204f54b0e Merge branch 'develop' into fix-phpstan-error-level-0-part2 2024-11-30 06:51:49 +00:00
72e7e2a5b7 Merge remote-tracking branch 'friendica/2024.09-rc' into develop 2024-11-29 21:15:25 -05:00
Art4
5f2a9e9891 Fix error in bluesky addon 2024-11-29 22:36:09 +00:00
Art4
a6de4225c6 Merge branch 'port-rc-branch-into-develop' into fix-phpstan-error-level-0-part2 2024-11-27 23:19:19 +00:00
Art4
23227e5b0f Fix classes in s3_storage addon 2024-11-27 23:18:20 +00:00
Art4
7872400467 Fix errors in pumpio addon 2024-11-27 23:14:01 +00:00
Art4
a5aaea5211 fix errors in pnut addon, add support for PHP 7.4 2024-11-27 22:55:15 +00:00
Art4
7453c6f41a fix error in PHPMailer 2024-11-27 22:33:12 +00:00
Art4
9cb728d19a Merge branch 'develop' into fix-phpstan-error-level-0-part2 2024-11-27 22:25:42 +00:00
Art4
e488f597be Fix errors in mailstream addon 2024-11-27 11:52:59 +00:00
Art4
1346a92505 Fix errors in libravatar addon 2024-11-27 11:43:21 +00:00
Art4
9117626c6a Fix errors in diaspora addon 2024-11-27 11:40:45 +00:00
Art4
90ffd40d58 remove wrong return tag 2024-11-27 11:38:55 +00:00
93a91a95e9 Merge pull request 'Fix PHPStan errors on level 0' (#1575) from MrPetovan/friendica-addons:bug/Art4-1367 into develop
Reviewed-on: friendica/friendica-addons#1575
2024-11-27 08:36:08 +01:00
Art4
fc0dda0cd9 refactor convert addon, replace each() calls with foreach loop 2024-11-26 08:23:27 +00:00
Art4
d7d6a43655 Add checks for CLD2Detector ans CLD2Encoding classes 2024-11-26 07:55:01 +00:00
Art4
c58ca7dcc9 Merge branch '2024.09-rc' into port-rc-branch-into-develop 2024-11-26 07:33:57 +00:00
Art4
6df91dd37b Fix errors in statusnet addon 2024-11-24 19:55:54 +00:00
Art4
e9d3afb483 Fix errors in tictac addon 2024-11-24 19:51:37 +00:00
Art4
348c44c972 inline slim routes and middlewares into advancedcontentfilter addon 2024-11-24 15:36:37 +00:00
58180bd732 Merge pull request 'Remove unused parameter in saml addon' (#1572) from MrPetovan/friendica-addons:bug/Art4-1366 into develop
Reviewed-on: friendica/friendica-addons#1572
2024-11-24 10:17:44 +01:00
Artur Weigandt
bf679262b0 Remove unused parameter in saml addon 2024-11-24 10:17:44 +01:00
c4e24833eb Merge pull request 'Remove unused parameter webdav_storage addon' (#1570) from MrPetovan/friendica-addons:bug/Art4-1364 into develop
Reviewed-on: friendica/friendica-addons#1570
2024-11-24 10:16:47 +01:00
Artur Weigandt
ecf0edb520 Remove unused parameter webdav_storage addon 2024-11-24 10:16:47 +01:00
3a5acf95f7 Merge pull request 'Remove unused App paramter in securemail addon' (#1571) from MrPetovan/friendica-addons:bug/Art4-1365 into develop
Reviewed-on: friendica/friendica-addons#1571
2024-11-24 10:16:25 +01:00
Artur Weigandt
2ea40dc897 Remove unused App paramter in securemail addon 2024-11-23 21:24:34 -05:00
867 changed files with 32977 additions and 4280 deletions

View file

@ -1,6 +1,6 @@
skip_clone: true
pipeline:
steps:
clone_friendica_base:
image: alpine/git
commands:
@ -56,6 +56,10 @@ pipeline:
- /tmp/drone-cache:/tmp/cache
when:
event: pull_request
phpstan:
image: friendicaci/php8.3:php8.3.3
commands:
- ./bin/composer.phar run phpstan;
check:
image: friendicaci/php-cs
commands:

View file

@ -0,0 +1,115 @@
# This prevents executing this pipeline at other servers than ci.friendi.ca
labels:
location: friendica
type: releaser
skip_clone: true
steps:
clone_friendica_base:
image: alpine/git
commands:
- git config --global user.email "no-reply@friendi.ca"
- git config --global user.name "Friendica"
- git config --global --add safe.directory $CI_WORKSPACE
- git clone https://github.com/friendica/friendica.git .
- git checkout $CI_COMMIT_BRANCH
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
clone_friendica_addon:
image: alpine/git
commands:
- git config --global user.email "no-reply@friendi.ca"
- git config --global user.name "Friendica"
- git clone $CI_REPO_CLONE_URL addon
- cd addon/
- git checkout $CI_COMMIT_BRANCH
- git fetch origin $CI_COMMIT_REF
- git merge $CI_COMMIT_SHA
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
restore_cache:
image: meltwater/drone-cache:dev
settings:
backend: "filesystem"
restore: true
cache_key: "{{ .Repo.Name }}_php7.4_{{ arch }}_{{ os }}"
archive_format: "gzip"
mount:
- '.composer'
volumes:
- /tmp/drone-cache:/tmp/cache
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
composer_install:
image: friendicaci/php8.2:php8.2.28
commands:
- export COMPOSER_HOME=.composer
- composer validate
- composer install --no-dev --optimize-autoloader
volumes:
- /etc/hosts:/etc/hosts
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
create_artifacts:
image: debian
commands:
- apt-get update
- apt-get install bzip2
- mkdir ./build
- export VERSION="$(cat VERSION)"
- export RELEASE="friendica-all-in-one-$VERSION"
- export ARTIFACT="$RELEASE.tar.gz"
- tar
--exclude='.tx'
--exclude='.git'
--exclude='.editorconfig'
--exclude='.gitattributes'
--exclude='.gitignore'
--exclude='.woodpecker'
--exclude='**/*/messages.po'
-cvzf ./build/$ARTIFACT /
- cd ./build
- sha256sum "$ARTIFACT" > "$ARTIFACT.sum256"
- chmod 664 ./*
- ls -lh
- cat "$ARTIFACT.sum256"
- sha256sum "$ARTIFACT"
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
sign_artifacts:
image: plugins/gpgsign
settings:
key:
from_secret: gpg_key
passphrase:
from_secret: gpg_password
files:
- build/*
exclude:
- build/*.sum256
detach_sign: true
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push
publish_artifacts:
image: alpine
commands:
- cp -fr build/* /tmp/friendica_files/
volumes:
- files:/tmp/friendica_files
when:
repo: friendica/friendica-addons
branch: [ develop, '*-rc' ]
event: push

View file

@ -5,7 +5,7 @@ labels:
skip_clone: true
pipeline:
steps:
clone_friendica_base:
image: alpine/git
commands:
@ -48,7 +48,7 @@ pipeline:
branch: [ develop, '*-rc' ]
event: push
composer_install:
image: friendicaci/php8.2:php8.2.16
image: friendicaci/php8.2:php8.2.28
commands:
- export COMPOSER_HOME=.composer
- composer validate

View file

@ -1,6 +1,6 @@
skip_clone: true
pipeline:
steps:
clone_friendica_base:
image: alpine/git
commands:

View file

@ -5,11 +5,13 @@ matrix:
- PHP_MAJOR_VERSION: 8.0
PHP_VERSION: 8.0.30
- PHP_MAJOR_VERSION: 8.1
PHP_VERSION: 8.1.27
PHP_VERSION: 8.1.31
- PHP_MAJOR_VERSION: 8.2
PHP_VERSION: 8.2.16
PHP_VERSION: 8.2.28
- PHP_MAJOR_VERSION: 8.3
PHP_VERSION: 8.3.3
PHP_VERSION: 8.3.17
- PHP_MAJOR_VERSION: 8.4
PHP_VERSION: 8.4.5
# This forces PHP Unit executions at the "opensocial" labeled location (because of much more power...)
labels:
@ -17,7 +19,7 @@ labels:
skip_clone: true
pipeline:
steps:
clone_friendica_base:
image: alpine/git
commands:
@ -98,9 +100,9 @@ pipeline:
- friendica/friendica-addons
commands:
- codecov -R '.' -Z -f 'clover.xml'
secrets:
- source: codecov-token
target: codecov_token
environment:
CODECOV_TOKEN:
from_secret: codecov-token
services:
mariadb:

View file

@ -5,7 +5,7 @@ labels:
skip_clone: true
pipeline:
steps:
clone_friendica_base:
image: alpine/git
commands:
@ -45,7 +45,7 @@ pipeline:
repo: friendica/friendica-addons
event: tag
composer_install:
image: friendicaci/php8.2:php8.2.16
image: friendicaci/php8.2:php8.2.28
commands:
- export COMPOSER_HOME=.composer
- composer validate

View file

@ -24,6 +24,6 @@ See the [documentation](https://github.com/friendica/friendica/blob/stable/doc/A
## Translation
Addons can be translated like any other part of Friendica.
Translation for addons is done at [the Transifex Friendica page](https://www.transifex.com/Friendica/friendica/dashboard/).
Translation for addons is done at [the Transifex Friendica page](https://app.transifex.com/Friendica/friendica/dashboard/).
Read more about the workflow in the [Friendica translation documentation](https://github.com/friendica/friendica/blob/stable/doc/translations.md#addon).

View file

@ -33,16 +33,13 @@
*
*/
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Content\Text\Markdown;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\Database\DBStructure;
use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Model\Tag;
use Friendica\Model\User;
@ -64,7 +61,7 @@ function advancedcontentfilter_install()
Hook::add('dbstructure_definition' , __FILE__, 'advancedcontentfilter_dbstructure_definition');
DBStructure::performUpdate();
Logger::notice('installed advancedcontentfilter');
DI::logger()->notice('installed advancedcontentfilter');
}
/*
@ -123,21 +120,22 @@ function advancedcontentfilter_prepare_body_content_filter(&$hook_data)
$expressionLanguage = new ExpressionLanguage\ExpressionLanguage();
}
if (!DI::userSession()->getLocalUserId()) {
$uid = $hook_data['uid'] ?? DI::userSession()->getLocalUserId();
if (!$uid) {
return;
}
$vars = advancedcontentfilter_get_filter_fields($hook_data['item']);
$rules = DI::cache()->get('rules_' . DI::userSession()->getLocalUserId());
$rules = DI::cache()->get('rules_' . $uid);
if (!isset($rules)) {
$rules = DBA::toArray(DBA::select(
'advancedcontentfilter_rules',
['name', 'expression', 'serialized'],
['uid' => DI::userSession()->getLocalUserId(), 'active' => true]
['uid' => $uid, 'active' => true]
));
DI::cache()->set('rules_' . DI::userSession()->getLocalUserId(), $rules);
DI::cache()->set('rules_' . $uid, $rules);
}
if ($rules) {
@ -192,9 +190,30 @@ function advancedcontentfilter_init()
if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] == 'api') {
$slim = \Slim\Factory\AppFactory::create();
require __DIR__ . '/src/middlewares.php';
/**
* The routing middleware should be added before the ErrorMiddleware
* Otherwise exceptions thrown from it will not be handled
*/
$slim->addRoutingMiddleware();
$slim->addErrorMiddleware(true, true, true, DI::logger());
// register routes
$slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->get('', 'advancedcontentfilter_get_rules');
$app->post('', 'advancedcontentfilter_post_rules');
$app->get('/{id}', 'advancedcontentfilter_get_rules_id');
$app->put('/{id}', 'advancedcontentfilter_put_rules_id');
$app->delete('/{id}', 'advancedcontentfilter_delete_rules_id');
});
$app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->get('/{guid}', 'advancedcontentfilter_get_variables_guid');
});
});
require __DIR__ . '/src/routes.php';
$slim->run();
exit;
@ -252,7 +271,7 @@ function advancedcontentfilter_content()
'rule_expression' => DI::l10n()->t('Rule Expression'),
'cancel' => DI::l10n()->t('Cancel'),
],
'$current_theme' => DI::app()->getCurrentTheme(),
'$current_theme' => DI::appHelper()->getCurrentTheme(),
'$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])),
'$form_security_token' => BaseModule::getFormSecurityToken()
]);

View file

@ -0,0 +1,161 @@
# ADDON advancedcontentfilter
# Copyright (C)
# This file is distributed under the same license as the Friendica advancedcontentfilter addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Language-Team: Bulgarian (https://app.transifex.com/Friendica/teams/12172/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: advancedcontentfilter.php:154
#, php-format
msgid "Filtered by rule: %s"
msgstr ""
#: advancedcontentfilter.php:170 advancedcontentfilter.php:225
msgid "Advanced Content Filter"
msgstr ""
#: advancedcontentfilter.php:224
msgid "Back to Addon Settings"
msgstr ""
#: advancedcontentfilter.php:226
msgid "Add a Rule"
msgstr ""
#: advancedcontentfilter.php:227
msgid "Help"
msgstr ""
#: advancedcontentfilter.php:228
msgid ""
"Add and manage your personal content filter rules in this screen. Rules have"
" a name and an arbitrary expression that will be matched against post data. "
"For a complete reference of the available operations and variables, check "
"the help page."
msgstr ""
#: advancedcontentfilter.php:229
msgid "Your rules"
msgstr ""
#: advancedcontentfilter.php:230
msgid ""
"You have no rules yet! Start adding one by clicking on the button above next"
" to the title."
msgstr ""
#: advancedcontentfilter.php:231
msgid "Disabled"
msgstr ""
#: advancedcontentfilter.php:232
msgid "Enabled"
msgstr ""
#: advancedcontentfilter.php:233
msgid "Disable this rule"
msgstr ""
#: advancedcontentfilter.php:234
msgid "Enable this rule"
msgstr ""
#: advancedcontentfilter.php:235
msgid "Edit this rule"
msgstr ""
#: advancedcontentfilter.php:236
msgid "Edit the rule"
msgstr ""
#: advancedcontentfilter.php:237
msgid "Save this rule"
msgstr ""
#: advancedcontentfilter.php:238
msgid "Delete this rule"
msgstr ""
#: advancedcontentfilter.php:239
msgid "Rule"
msgstr ""
#: advancedcontentfilter.php:240
msgid "Close"
msgstr ""
#: advancedcontentfilter.php:241
msgid "Add new rule"
msgstr ""
#: advancedcontentfilter.php:242
msgid "Rule Name"
msgstr ""
#: advancedcontentfilter.php:243
msgid "Rule Expression"
msgstr ""
#: advancedcontentfilter.php:244
msgid "Cancel"
msgstr ""
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr ""
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383
#: advancedcontentfilter.php:414 advancedcontentfilter.php:437
msgid "You must be logged in to use this method"
msgstr ""
#: advancedcontentfilter.php:351 advancedcontentfilter.php:387
#: advancedcontentfilter.php:418
msgid "Invalid form security token, please refresh the page."
msgstr ""
#: advancedcontentfilter.php:363
msgid "The rule name and expression are required."
msgstr ""
#: advancedcontentfilter.php:377
msgid "Rule successfully added"
msgstr ""
#: advancedcontentfilter.php:391 advancedcontentfilter.php:422
msgid "Rule doesn't exist or doesn't belong to you."
msgstr ""
#: advancedcontentfilter.php:408
msgid "Rule successfully updated"
msgstr ""
#: advancedcontentfilter.php:431
msgid "Rule successfully deleted"
msgstr ""
#: advancedcontentfilter.php:441
msgid "Missing argument: guid."
msgstr ""
#: advancedcontentfilter.php:449
#, php-format
msgid "Unknown post with guid: %s"
msgstr ""
#: src/middlewares.php:49
msgid "Method not found"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,161 @@
# ADDON advancedcontentfilter
# Copyright (C)
# This file is distributed under the same license as the Friendica advancedcontentfilter addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Language-Team: Esperanto (https://app.transifex.com/Friendica/teams/12172/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: advancedcontentfilter.php:154
#, php-format
msgid "Filtered by rule: %s"
msgstr ""
#: advancedcontentfilter.php:170 advancedcontentfilter.php:225
msgid "Advanced Content Filter"
msgstr ""
#: advancedcontentfilter.php:224
msgid "Back to Addon Settings"
msgstr ""
#: advancedcontentfilter.php:226
msgid "Add a Rule"
msgstr ""
#: advancedcontentfilter.php:227
msgid "Help"
msgstr ""
#: advancedcontentfilter.php:228
msgid ""
"Add and manage your personal content filter rules in this screen. Rules have"
" a name and an arbitrary expression that will be matched against post data. "
"For a complete reference of the available operations and variables, check "
"the help page."
msgstr ""
#: advancedcontentfilter.php:229
msgid "Your rules"
msgstr ""
#: advancedcontentfilter.php:230
msgid ""
"You have no rules yet! Start adding one by clicking on the button above next"
" to the title."
msgstr ""
#: advancedcontentfilter.php:231
msgid "Disabled"
msgstr ""
#: advancedcontentfilter.php:232
msgid "Enabled"
msgstr ""
#: advancedcontentfilter.php:233
msgid "Disable this rule"
msgstr ""
#: advancedcontentfilter.php:234
msgid "Enable this rule"
msgstr ""
#: advancedcontentfilter.php:235
msgid "Edit this rule"
msgstr ""
#: advancedcontentfilter.php:236
msgid "Edit the rule"
msgstr ""
#: advancedcontentfilter.php:237
msgid "Save this rule"
msgstr ""
#: advancedcontentfilter.php:238
msgid "Delete this rule"
msgstr ""
#: advancedcontentfilter.php:239
msgid "Rule"
msgstr ""
#: advancedcontentfilter.php:240
msgid "Close"
msgstr ""
#: advancedcontentfilter.php:241
msgid "Add new rule"
msgstr ""
#: advancedcontentfilter.php:242
msgid "Rule Name"
msgstr ""
#: advancedcontentfilter.php:243
msgid "Rule Expression"
msgstr ""
#: advancedcontentfilter.php:244
msgid "Cancel"
msgstr ""
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr ""
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383
#: advancedcontentfilter.php:414 advancedcontentfilter.php:437
msgid "You must be logged in to use this method"
msgstr ""
#: advancedcontentfilter.php:351 advancedcontentfilter.php:387
#: advancedcontentfilter.php:418
msgid "Invalid form security token, please refresh the page."
msgstr ""
#: advancedcontentfilter.php:363
msgid "The rule name and expression are required."
msgstr ""
#: advancedcontentfilter.php:377
msgid "Rule successfully added"
msgstr ""
#: advancedcontentfilter.php:391 advancedcontentfilter.php:422
msgid "Rule doesn't exist or doesn't belong to you."
msgstr ""
#: advancedcontentfilter.php:408
msgid "Rule successfully updated"
msgstr ""
#: advancedcontentfilter.php:431
msgid "Rule successfully deleted"
msgstr ""
#: advancedcontentfilter.php:441
msgid "Missing argument: guid."
msgstr ""
#: advancedcontentfilter.php:449
#, php-format
msgid "Unknown post with guid: %s"
msgstr ""
#: src/middlewares.php:49
msgid "Method not found"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,161 @@
# ADDON advancedcontentfilter
# Copyright (C)
# This file is distributed under the same license as the Friendica advancedcontentfilter addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Language-Team: Estonian (https://app.transifex.com/Friendica/teams/12172/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: advancedcontentfilter.php:154
#, php-format
msgid "Filtered by rule: %s"
msgstr ""
#: advancedcontentfilter.php:170 advancedcontentfilter.php:225
msgid "Advanced Content Filter"
msgstr ""
#: advancedcontentfilter.php:224
msgid "Back to Addon Settings"
msgstr ""
#: advancedcontentfilter.php:226
msgid "Add a Rule"
msgstr ""
#: advancedcontentfilter.php:227
msgid "Help"
msgstr ""
#: advancedcontentfilter.php:228
msgid ""
"Add and manage your personal content filter rules in this screen. Rules have"
" a name and an arbitrary expression that will be matched against post data. "
"For a complete reference of the available operations and variables, check "
"the help page."
msgstr ""
#: advancedcontentfilter.php:229
msgid "Your rules"
msgstr ""
#: advancedcontentfilter.php:230
msgid ""
"You have no rules yet! Start adding one by clicking on the button above next"
" to the title."
msgstr ""
#: advancedcontentfilter.php:231
msgid "Disabled"
msgstr ""
#: advancedcontentfilter.php:232
msgid "Enabled"
msgstr ""
#: advancedcontentfilter.php:233
msgid "Disable this rule"
msgstr ""
#: advancedcontentfilter.php:234
msgid "Enable this rule"
msgstr ""
#: advancedcontentfilter.php:235
msgid "Edit this rule"
msgstr ""
#: advancedcontentfilter.php:236
msgid "Edit the rule"
msgstr ""
#: advancedcontentfilter.php:237
msgid "Save this rule"
msgstr ""
#: advancedcontentfilter.php:238
msgid "Delete this rule"
msgstr ""
#: advancedcontentfilter.php:239
msgid "Rule"
msgstr ""
#: advancedcontentfilter.php:240
msgid "Close"
msgstr ""
#: advancedcontentfilter.php:241
msgid "Add new rule"
msgstr ""
#: advancedcontentfilter.php:242
msgid "Rule Name"
msgstr ""
#: advancedcontentfilter.php:243
msgid "Rule Expression"
msgstr ""
#: advancedcontentfilter.php:244
msgid "Cancel"
msgstr ""
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr ""
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383
#: advancedcontentfilter.php:414 advancedcontentfilter.php:437
msgid "You must be logged in to use this method"
msgstr ""
#: advancedcontentfilter.php:351 advancedcontentfilter.php:387
#: advancedcontentfilter.php:418
msgid "Invalid form security token, please refresh the page."
msgstr ""
#: advancedcontentfilter.php:363
msgid "The rule name and expression are required."
msgstr ""
#: advancedcontentfilter.php:377
msgid "Rule successfully added"
msgstr ""
#: advancedcontentfilter.php:391 advancedcontentfilter.php:422
msgid "Rule doesn't exist or doesn't belong to you."
msgstr ""
#: advancedcontentfilter.php:408
msgid "Rule successfully updated"
msgstr ""
#: advancedcontentfilter.php:431
msgid "Rule successfully deleted"
msgstr ""
#: advancedcontentfilter.php:441
msgid "Missing argument: guid."
msgstr ""
#: advancedcontentfilter.php:449
#, php-format
msgid "Unknown post with guid: %s"
msgstr ""
#: src/middlewares.php:49
msgid "Method not found"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,161 @@
# ADDON advancedcontentfilter
# Copyright (C)
# This file is distributed under the same license as the Friendica advancedcontentfilter addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Language-Team: Gaelic, Scottish (https://app.transifex.com/Friendica/teams/12172/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: advancedcontentfilter.php:154
#, php-format
msgid "Filtered by rule: %s"
msgstr ""
#: advancedcontentfilter.php:170 advancedcontentfilter.php:225
msgid "Advanced Content Filter"
msgstr ""
#: advancedcontentfilter.php:224
msgid "Back to Addon Settings"
msgstr ""
#: advancedcontentfilter.php:226
msgid "Add a Rule"
msgstr ""
#: advancedcontentfilter.php:227
msgid "Help"
msgstr ""
#: advancedcontentfilter.php:228
msgid ""
"Add and manage your personal content filter rules in this screen. Rules have"
" a name and an arbitrary expression that will be matched against post data. "
"For a complete reference of the available operations and variables, check "
"the help page."
msgstr ""
#: advancedcontentfilter.php:229
msgid "Your rules"
msgstr ""
#: advancedcontentfilter.php:230
msgid ""
"You have no rules yet! Start adding one by clicking on the button above next"
" to the title."
msgstr ""
#: advancedcontentfilter.php:231
msgid "Disabled"
msgstr ""
#: advancedcontentfilter.php:232
msgid "Enabled"
msgstr ""
#: advancedcontentfilter.php:233
msgid "Disable this rule"
msgstr ""
#: advancedcontentfilter.php:234
msgid "Enable this rule"
msgstr ""
#: advancedcontentfilter.php:235
msgid "Edit this rule"
msgstr ""
#: advancedcontentfilter.php:236
msgid "Edit the rule"
msgstr ""
#: advancedcontentfilter.php:237
msgid "Save this rule"
msgstr ""
#: advancedcontentfilter.php:238
msgid "Delete this rule"
msgstr ""
#: advancedcontentfilter.php:239
msgid "Rule"
msgstr ""
#: advancedcontentfilter.php:240
msgid "Close"
msgstr ""
#: advancedcontentfilter.php:241
msgid "Add new rule"
msgstr ""
#: advancedcontentfilter.php:242
msgid "Rule Name"
msgstr ""
#: advancedcontentfilter.php:243
msgid "Rule Expression"
msgstr ""
#: advancedcontentfilter.php:244
msgid "Cancel"
msgstr ""
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr ""
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383
#: advancedcontentfilter.php:414 advancedcontentfilter.php:437
msgid "You must be logged in to use this method"
msgstr ""
#: advancedcontentfilter.php:351 advancedcontentfilter.php:387
#: advancedcontentfilter.php:418
msgid "Invalid form security token, please refresh the page."
msgstr ""
#: advancedcontentfilter.php:363
msgid "The rule name and expression are required."
msgstr ""
#: advancedcontentfilter.php:377
msgid "Rule successfully added"
msgstr ""
#: advancedcontentfilter.php:391 advancedcontentfilter.php:422
msgid "Rule doesn't exist or doesn't belong to you."
msgstr ""
#: advancedcontentfilter.php:408
msgid "Rule successfully updated"
msgstr ""
#: advancedcontentfilter.php:431
msgid "Rule successfully deleted"
msgstr ""
#: advancedcontentfilter.php:441
msgid "Missing argument: guid."
msgstr ""
#: advancedcontentfilter.php:449
#, php-format
msgid "Unknown post with guid: %s"
msgstr ""
#: src/middlewares.php:49
msgid "Method not found"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,161 @@
# ADDON advancedcontentfilter
# Copyright (C)
# This file is distributed under the same license as the Friendica advancedcontentfilter addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Language-Team: Icelandic (https://app.transifex.com/Friendica/teams/12172/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: advancedcontentfilter.php:154
#, php-format
msgid "Filtered by rule: %s"
msgstr ""
#: advancedcontentfilter.php:170 advancedcontentfilter.php:225
msgid "Advanced Content Filter"
msgstr ""
#: advancedcontentfilter.php:224
msgid "Back to Addon Settings"
msgstr ""
#: advancedcontentfilter.php:226
msgid "Add a Rule"
msgstr ""
#: advancedcontentfilter.php:227
msgid "Help"
msgstr ""
#: advancedcontentfilter.php:228
msgid ""
"Add and manage your personal content filter rules in this screen. Rules have"
" a name and an arbitrary expression that will be matched against post data. "
"For a complete reference of the available operations and variables, check "
"the help page."
msgstr ""
#: advancedcontentfilter.php:229
msgid "Your rules"
msgstr ""
#: advancedcontentfilter.php:230
msgid ""
"You have no rules yet! Start adding one by clicking on the button above next"
" to the title."
msgstr ""
#: advancedcontentfilter.php:231
msgid "Disabled"
msgstr ""
#: advancedcontentfilter.php:232
msgid "Enabled"
msgstr ""
#: advancedcontentfilter.php:233
msgid "Disable this rule"
msgstr ""
#: advancedcontentfilter.php:234
msgid "Enable this rule"
msgstr ""
#: advancedcontentfilter.php:235
msgid "Edit this rule"
msgstr ""
#: advancedcontentfilter.php:236
msgid "Edit the rule"
msgstr ""
#: advancedcontentfilter.php:237
msgid "Save this rule"
msgstr ""
#: advancedcontentfilter.php:238
msgid "Delete this rule"
msgstr ""
#: advancedcontentfilter.php:239
msgid "Rule"
msgstr ""
#: advancedcontentfilter.php:240
msgid "Close"
msgstr ""
#: advancedcontentfilter.php:241
msgid "Add new rule"
msgstr ""
#: advancedcontentfilter.php:242
msgid "Rule Name"
msgstr ""
#: advancedcontentfilter.php:243
msgid "Rule Expression"
msgstr ""
#: advancedcontentfilter.php:244
msgid "Cancel"
msgstr ""
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr ""
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383
#: advancedcontentfilter.php:414 advancedcontentfilter.php:437
msgid "You must be logged in to use this method"
msgstr ""
#: advancedcontentfilter.php:351 advancedcontentfilter.php:387
#: advancedcontentfilter.php:418
msgid "Invalid form security token, please refresh the page."
msgstr ""
#: advancedcontentfilter.php:363
msgid "The rule name and expression are required."
msgstr ""
#: advancedcontentfilter.php:377
msgid "Rule successfully added"
msgstr ""
#: advancedcontentfilter.php:391 advancedcontentfilter.php:422
msgid "Rule doesn't exist or doesn't belong to you."
msgstr ""
#: advancedcontentfilter.php:408
msgid "Rule successfully updated"
msgstr ""
#: advancedcontentfilter.php:431
msgid "Rule successfully deleted"
msgstr ""
#: advancedcontentfilter.php:441
msgid "Missing argument: guid."
msgstr ""
#: advancedcontentfilter.php:449
#, php-format
msgid "Unknown post with guid: %s"
msgstr ""
#: src/middlewares.php:49
msgid "Method not found"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -6,7 +6,7 @@
# Translators:
# Waldemar Stoczkowski, 2018
# Joe Doe, 2021
# Piotr Strębski <strebski@gmail.com>, 2022
# Bartosz Kozień, 2025
#
#, fuzzy
msgid ""
@ -15,8 +15,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-11 08:54-0400\n"
"PO-Revision-Date: 2018-05-24 06:41+0000\n"
"Last-Translator: Piotr Strębski <strebski@gmail.com>, 2022\n"
"Language-Team: Polish (https://www.transifex.com/Friendica/teams/12172/pl/)\n"
"Last-Translator: Bartosz Kozień, 2025\n"
"Language-Team: Polish (https://app.transifex.com/Friendica/teams/12172/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -126,7 +126,7 @@ msgstr "Anuluj"
#: advancedcontentfilter.php:295
msgid "This addon requires this node having at least one post"
msgstr "Ten dodatek wymaga, aby ten węzeł miał co najmniej jeden wpis"
msgstr "Ten dodatek wymaga, aby ta instancja miała co najmniej jeden wpis"
#: advancedcontentfilter.php:325 advancedcontentfilter.php:336
#: advancedcontentfilter.php:347 advancedcontentfilter.php:383

View file

@ -27,7 +27,7 @@ $a->strings['Add new rule'] = 'Dodaj nową regułę';
$a->strings['Rule Name'] = 'Nazwa reguły';
$a->strings['Rule Expression'] = 'Wyrażanie reguły';
$a->strings['Cancel'] = 'Anuluj';
$a->strings['This addon requires this node having at least one post'] = 'Ten dodatek wymaga, aby ten węzeł miał co najmniej jeden wpis';
$a->strings['This addon requires this node having at least one post'] = 'Ten dodatek wymaga, aby ta instancja miała co najmniej jeden wpis';
$a->strings['You must be logged in to use this method'] = 'Musisz być zalogowany, aby skorzystać z tej metody';
$a->strings['Invalid form security token, please refresh the page.'] = 'Nieprawidłowy token zabezpieczający formularz, odśwież stronę.';
$a->strings['The rule name and expression are required.'] = 'Nazwa reguły i wyrażenie są wymagane.';

View file

@ -1,32 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2020, Friendica
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
use Friendica\DI;
/** @var $slim \Slim\App */
/**
* The routing middleware should be added before the ErrorMiddleware
* Otherwise exceptions thrown from it will not be handled
*/
$slim->addRoutingMiddleware();
$errorMiddleware = $slim->addErrorMiddleware(true, true, true, DI::logger());

View file

@ -1,36 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2020, Friendica
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* @var $slim Slim\App */
$slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->get('', 'advancedcontentfilter_get_rules');
$app->post('', 'advancedcontentfilter_post_rules');
$app->get('/{id}', 'advancedcontentfilter_get_rules_id');
$app->put('/{id}', 'advancedcontentfilter_put_rules_id');
$app->delete('/{id}', 'advancedcontentfilter_delete_rules_id');
});
$app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) {
$app->get('/{guid}', 'advancedcontentfilter_get_variables_guid');
});
});

View file

@ -6,6 +6,7 @@
* Author: Stephen Mahood <https://friends.mayfirst.org/profile/marxistvegan>
* Author: Tobias Diekershoff <https://f.diekershoff.de/profile/tobias>
* Author: Matthias Ebers <https://loma.ml/profile/feb>
* Status: Unsupported
*/
use Friendica\Core\Hook;

View file

@ -6,9 +6,7 @@
* Author: Fabio <https://kirgroup.com/profile/fabrixxm>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\DI;
@ -28,7 +26,7 @@ function birdavatar_install()
Hook::register('addon_settings', __FILE__, 'birdavatar_addon_settings');
Hook::register('addon_settings_post', __FILE__, 'birdavatar_addon_settings_post');
Logger::info('registered birdavatar');
DI::logger()->info('registered birdavatar');
}
/**

View file

@ -44,9 +44,7 @@
* THE SOFTWARE.
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\DI;
@ -78,7 +76,7 @@ function blackout_redirect ($b)
}
if (( $date1 <= $now ) && ( $now <= $date2 )) {
Logger::notice('redirecting user to blackout page');
DI::logger()->notice('redirecting user to blackout page');
System::externalRedirect($myurl);
}
}

View file

@ -0,0 +1,66 @@
# ADDON blackout
# Copyright (C)
# This file is distributed under the same license as the Friendica blackout addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:19+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: blackout.php:97
msgid ""
"The end-date is prior to the start-date of the blackout, you should fix "
"this."
msgstr ""
#: blackout.php:99
#, php-format
msgid ""
"Please double check the current settings for the blackout. It will begin on "
"<strong>%s</strong> and end on <strong>%s</strong>."
msgstr ""
#: blackout.php:102
msgid "Save Settings"
msgstr ""
#: blackout.php:103
msgid "Redirect URL"
msgstr ""
#: blackout.php:103
msgid "All your visitors from the web will be redirected to this URL."
msgstr ""
#: blackout.php:104
msgid "Begin of the Blackout"
msgstr ""
#: blackout.php:104
msgid ""
"Format is <tt>YYYY-MM-DD hh:mm</tt>; <em>YYYY</em> year, <em>MM</em> month, "
"<em>DD</em> day, <em>hh</em> hour and <em>mm</em> minute."
msgstr ""
#: blackout.php:105
msgid "End of the Blackout"
msgstr ""
#: blackout.php:107
msgid ""
"<strong>Note</strong>: The redirect will be active from the moment you press"
" the submit button. Users currently logged in will <strong>not</strong> be "
"thrown out but can't login again after logging out while the blackout is "
"still in place."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,66 @@
# ADDON blackout
# Copyright (C)
# This file is distributed under the same license as the Friendica blackout addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:19+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: blackout.php:97
msgid ""
"The end-date is prior to the start-date of the blackout, you should fix "
"this."
msgstr ""
#: blackout.php:99
#, php-format
msgid ""
"Please double check the current settings for the blackout. It will begin on "
"<strong>%s</strong> and end on <strong>%s</strong>."
msgstr ""
#: blackout.php:102
msgid "Save Settings"
msgstr ""
#: blackout.php:103
msgid "Redirect URL"
msgstr ""
#: blackout.php:103
msgid "All your visitors from the web will be redirected to this URL."
msgstr ""
#: blackout.php:104
msgid "Begin of the Blackout"
msgstr ""
#: blackout.php:104
msgid ""
"Format is <tt>YYYY-MM-DD hh:mm</tt>; <em>YYYY</em> year, <em>MM</em> month, "
"<em>DD</em> day, <em>hh</em> hour and <em>mm</em> minute."
msgstr ""
#: blackout.php:105
msgid "End of the Blackout"
msgstr ""
#: blackout.php:107
msgid ""
"<strong>Note</strong>: The redirect will be active from the moment you press"
" the submit button. Users currently logged in will <strong>not</strong> be "
"thrown out but can't login again after logging out while the blackout is "
"still in place."
msgstr ""

View file

@ -1,3 +1,7 @@
<?php
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,66 @@
# ADDON blackout
# Copyright (C)
# This file is distributed under the same license as the Friendica blackout addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:19+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: blackout.php:97
msgid ""
"The end-date is prior to the start-date of the blackout, you should fix "
"this."
msgstr ""
#: blackout.php:99
#, php-format
msgid ""
"Please double check the current settings for the blackout. It will begin on "
"<strong>%s</strong> and end on <strong>%s</strong>."
msgstr ""
#: blackout.php:102
msgid "Save Settings"
msgstr ""
#: blackout.php:103
msgid "Redirect URL"
msgstr ""
#: blackout.php:103
msgid "All your visitors from the web will be redirected to this URL."
msgstr ""
#: blackout.php:104
msgid "Begin of the Blackout"
msgstr ""
#: blackout.php:104
msgid ""
"Format is <tt>YYYY-MM-DD hh:mm</tt>; <em>YYYY</em> year, <em>MM</em> month, "
"<em>DD</em> day, <em>hh</em> hour and <em>mm</em> minute."
msgstr ""
#: blackout.php:105
msgid "End of the Blackout"
msgstr ""
#: blackout.php:107
msgid ""
"<strong>Note</strong>: The redirect will be active from the moment you press"
" the submit button. Users currently logged in will <strong>not</strong> be "
"thrown out but can't login again after logging out while the blackout is "
"still in place."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,66 @@
# ADDON blackout
# Copyright (C)
# This file is distributed under the same license as the Friendica blackout addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:19+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: blackout.php:97
msgid ""
"The end-date is prior to the start-date of the blackout, you should fix "
"this."
msgstr ""
#: blackout.php:99
#, php-format
msgid ""
"Please double check the current settings for the blackout. It will begin on "
"<strong>%s</strong> and end on <strong>%s</strong>."
msgstr ""
#: blackout.php:102
msgid "Save Settings"
msgstr ""
#: blackout.php:103
msgid "Redirect URL"
msgstr ""
#: blackout.php:103
msgid "All your visitors from the web will be redirected to this URL."
msgstr ""
#: blackout.php:104
msgid "Begin of the Blackout"
msgstr ""
#: blackout.php:104
msgid ""
"Format is <tt>YYYY-MM-DD hh:mm</tt>; <em>YYYY</em> year, <em>MM</em> month, "
"<em>DD</em> day, <em>hh</em> hour and <em>mm</em> minute."
msgstr ""
#: blackout.php:105
msgid "End of the Blackout"
msgstr ""
#: blackout.php:107
msgid ""
"<strong>Note</strong>: The redirect will be active from the moment you press"
" the submit button. Users currently logged in will <strong>not</strong> be "
"thrown out but can't login again after logging out while the blackout is "
"still in place."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -11,7 +11,6 @@
use Friendica\Core\Hook;
use Friendica\DI;
use Jaybizzle\CrawlerDetect\CrawlerDetect;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Network\HTTPException\ForbiddenException;
@ -70,7 +69,7 @@ function blockbot_init_1()
}
if (empty($parts)) {
Logger::debug('Known frontend found - accept', $logdata);
DI::logger()->debug('Known frontend found - accept', $logdata);
if ($isCrawler) {
blockbot_save('badly-parsed-agents', $_SERVER['HTTP_USER_AGENT']);
}
@ -80,66 +79,66 @@ function blockbot_init_1()
blockbot_log_activitypub($_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT']);
if (blockbot_is_crawler($parts)) {
Logger::debug('Crawler found - reject', $logdata);
DI::logger()->debug('Crawler found - reject', $logdata);
blockbot_reject();
}
if (blockbot_is_searchbot($parts)) {
Logger::debug('Search bot found - reject', $logdata);
DI::logger()->debug('Search bot found - reject', $logdata);
blockbot_reject();
}
if (blockbot_is_unwanted($parts)) {
Logger::debug('Uncategorized unwanted agent found - reject', $logdata);
DI::logger()->debug('Uncategorized unwanted agent found - reject', $logdata);
blockbot_reject();
}
if (blockbot_is_security_checker($parts)) {
if (!DI::config()->get('blockbot', 'security_checker')) {
Logger::debug('Security checker found - reject', $logdata);
DI::logger()->debug('Security checker found - reject', $logdata);
blockbot_reject();
}
Logger::debug('Security checker found - accept', $logdata);
DI::logger()->debug('Security checker found - accept', $logdata);
return;
}
if (blockbot_is_social_media($parts)) {
Logger::debug('Social media service found - accept', $logdata);
DI::logger()->debug('Social media service found - accept', $logdata);
return;
}
if (blockbot_is_fediverse_client($parts)) {
Logger::debug('Fediverse client found - accept', $logdata);
DI::logger()->debug('Fediverse client found - accept', $logdata);
return;
}
if (blockbot_is_feed_reader($parts)) {
Logger::debug('Feed reader found - accept', $logdata);
DI::logger()->debug('Feed reader found - accept', $logdata);
return;
}
if (blockbot_is_fediverse_tool($parts)) {
Logger::debug('Fediverse tool found - accept', $logdata);
DI::logger()->debug('Fediverse tool found - accept', $logdata);
return;
}
if (blockbot_is_service_agent($parts)) {
Logger::debug('Service agent found - accept', $logdata);
DI::logger()->debug('Service agent found - accept', $logdata);
return;
}
if (blockbot_is_monitor($parts)) {
Logger::debug('Monitoring service found - accept', $logdata);
DI::logger()->debug('Monitoring service found - accept', $logdata);
return;
}
if (blockbot_is_validator($parts)) {
Logger::debug('Validation service found - accept', $logdata);
DI::logger()->debug('Validation service found - accept', $logdata);
return;
}
if (blockbot_is_good_tool($parts)) {
Logger::debug('Uncategorized helpful service found - accept', $logdata);
DI::logger()->debug('Uncategorized helpful service found - accept', $logdata);
return;
}
@ -147,10 +146,10 @@ function blockbot_init_1()
if (blockbot_is_http_library($parts)) {
blockbot_check_login_attempt($_SERVER['REQUEST_URI'], $logdata);
if (!DI::config()->get('blockbot', 'http_libraries')) {
Logger::debug('HTTP Library found - reject', $logdata);
DI::logger()->debug('HTTP Library found - reject', $logdata);
blockbot_reject();
}
Logger::debug('HTTP Library found - accept', $logdata);
DI::logger()->debug('HTTP Library found - accept', $logdata);
return;
}
@ -161,12 +160,12 @@ function blockbot_init_1()
if (!$isCrawler) {
blockbot_save('good-agents', $_SERVER['HTTP_USER_AGENT']);
Logger::debug('Non-bot user agent detected', $logdata);
DI::logger()->debug('Non-bot user agent detected', $logdata);
return;
}
blockbot_save('bad-agents', $_SERVER['HTTP_USER_AGENT']);
Logger::notice('Possible bot found - reject', $logdata);
DI::logger()->notice('Possible bot found - reject', $logdata);
blockbot_reject();
}
@ -209,7 +208,7 @@ function blockbot_log_activitypub(string $url, string $agent)
blockbot_save('activitypub-inbox-agents', $agent);
}
if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER))) {
if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER, false))) {
blockbot_save('activitypub-signature-agents', $agent);
}
}
@ -217,7 +216,7 @@ function blockbot_log_activitypub(string $url, string $agent)
function blockbot_check_login_attempt(string $url, array $logdata)
{
if (in_array(trim(parse_url($url, PHP_URL_PATH), '/'), ['login', 'lostpass', 'register'])) {
Logger::debug('Login attempt detected - reject', $logdata);
DI::logger()->debug('Login attempt detected - reject', $logdata);
blockbot_reject();
}
}
@ -443,7 +442,7 @@ function blockbot_is_monitor(array $parts): bool
}
/**
* Services in the centralized and decentralized social media environment
* Services in the centralized and decentralized social media environment
*
* @param array $parts
* @return boolean

View file

@ -1,7 +1,7 @@
<?php
/**
* Name: Bluesky Connector
* Description: Post to Bluesky, import timelines and feeds
* Name: AT Protocol Connector (Bluesky, Eurosky, Blacksky, ...)
* Description: Post via AT Protocol, import timelines and feeds
* Version: 1.1
* Author: Michael Vogel <https://pirati.ca/profile/heluecht>
*
@ -30,7 +30,6 @@ use Friendica\Content\Text\Plaintext;
use Friendica\Core\Cache\Enum\Duration;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
use Friendica\Core\Worker;
@ -47,6 +46,7 @@ use Friendica\Protocol\Activity;
use Friendica\Protocol\ATProtocol;
use Friendica\Protocol\Relay;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\ParseUrl;
use Friendica\Util\Strings;
const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes
@ -73,7 +73,7 @@ function bluesky_install()
function bluesky_load_config(ConfigFileManager $loader)
{
DI::app()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
}
function bluesky_check_item_notification(array &$notification_data)
@ -82,6 +82,8 @@ function bluesky_check_item_notification(array &$notification_data)
return;
}
DI::atProtocol()->setApiForUser($notification_data['uid']);
$did = DI::atProtocol()->getUserDid($notification_data['uid']);
if (empty($did)) {
return;
@ -97,27 +99,17 @@ function bluesky_item_by_link(array &$hookData)
return;
}
$token = DI::atProtocol()->getUserToken($hookData['uid']);
if (empty($token)) {
return;
DI::atProtocol()->setApiForUser($hookData['uid']);
if (!str_starts_with($hookData['uri'], 'at://')) {
$data = ParseUrl::getSiteinfoCached($hookData['uri']);
$uri = $data['atprotocol']['uri'] ?? '';
} else {
$uri = $hookData['uri'];
}
// @todo also support the URI format (at://did/app.bsky.feed.post/cid)
if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) {
return;
}
$did = DI::atProtocol()->getDid($matches[1]);
if (empty($did)) {
return;
}
Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]);
$uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2];
$uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0);
Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]);
$uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0, '', false, Conversation::PARCEL_CONNECTOR);
DI::logger()->debug('Got post', ['uri' => $uri]);
if (!empty($uri)) {
$item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]);
if (!empty($item['id'])) {
@ -128,20 +120,22 @@ function bluesky_item_by_link(array &$hookData)
function bluesky_support_follow(array &$data)
{
if ($data['protocol'] == Protocol::BLUESKY) {
if ($data['protocol'] == Protocol::ATPROTO) {
$data['result'] = true;
}
}
function bluesky_follow(array &$hook_data)
{
DI::atProtocol()->setApiForUser($hook_data['uid']);
$token = DI::atProtocol()->getUserToken($hook_data['uid']);
if (empty($token)) {
return;
}
Logger::debug('Check if contact is bluesky', ['data' => $hook_data]);
$contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]);
DI::logger()->debug('Check if contact is AT Protocol', ['data' => $hook_data]);
$contact = DBA::selectFirst('contact', [], ['network' => Protocol::ATPROTO, 'nurl' => Strings::normaliseLink($hook_data['url']), 'uid' => [0, $hook_data['uid']]]);
if (empty($contact)) {
return;
}
@ -161,18 +155,20 @@ function bluesky_follow(array &$hook_data)
$activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post);
if (!empty($activity->uri)) {
$hook_data['contact'] = $contact;
Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]);
DI::logger()->debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]);
}
}
function bluesky_unfollow(array &$hook_data)
{
DI::atProtocol()->setApiForUser($hook_data['uid']);
$token = DI::atProtocol()->getUserToken($hook_data['uid']);
if (empty($token)) {
return;
}
if ($hook_data['contact']['network'] != Protocol::BLUESKY) {
if ($hook_data['contact']['network'] != Protocol::ATPROTO) {
return;
}
@ -188,12 +184,14 @@ function bluesky_unfollow(array &$hook_data)
function bluesky_block(array &$hook_data)
{
DI::atProtocol()->setApiForUser($hook_data['uid']);
$token = DI::atProtocol()->getUserToken($hook_data['uid']);
if (empty($token)) {
return;
}
if ($hook_data['contact']['network'] != Protocol::BLUESKY) {
if ($hook_data['contact']['network'] != Protocol::ATPROTO) {
return;
}
@ -215,18 +213,20 @@ function bluesky_block(array &$hook_data)
if ($ucid) {
Contact::remove($ucid);
}
Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]);
DI::logger()->debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]);
}
}
function bluesky_unblock(array &$hook_data)
{
DI::atProtocol()->setApiForUser($hook_data['uid']);
$token = DI::atProtocol()->getUserToken($hook_data['uid']);
if (empty($token)) {
return;
}
if ($hook_data['contact']['network'] != Protocol::BLUESKY) {
if ($hook_data['contact']['network'] != Protocol::ATPROTO) {
return;
}
@ -246,7 +246,7 @@ function bluesky_addon_admin(string &$o)
$o = Renderer::replaceMacros($t, [
'$submit' => DI::l10n()->t('Save Settings'),
'$friendica_handles' => ['friendica_handles', DI::l10n()->t('Allow your users to use your hostname for their Bluesky handles'), DI::config()->get('bluesky', 'friendica_handles'), DI::l10n()->t('Before enabling this option, you have to setup a wildcard domain configuration and you have to enable wildcard requests in your webserver configuration. On Apache this is done by adding "ServerAlias *.%s" to your HTTP configuration. You don\'t need to change the HTTPS configuration.', DI::baseUrl()->getHost())],
'$friendica_handles' => ['friendica_handles', DI::l10n()->t('Allow your users to use your hostname for their AT Protocol handles'), DI::config()->get('bluesky', 'friendica_handles'), DI::l10n()->t('Before enabling this option, you have to setup a wildcard domain configuration and you have to enable wildcard requests in your webserver configuration. On Apache this is done by adding "ServerAlias *.%s" to your HTTP configuration. You don\'t need to change the HTTPS configuration.', DI::baseUrl()->getHost())],
]);
}
@ -261,10 +261,13 @@ function bluesky_settings(array &$data)
return;
}
DI::atProtocol()->setApiForUser(DI::userSession()->getLocalUserId());
$enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false;
$def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false;
$pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds');
$handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle');
$web = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'web');
$did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId());
$token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token');
$import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false;
@ -275,7 +278,7 @@ function bluesky_settings(array &$data)
if (DI::config()->get('bluesky', 'friendica_handles')) {
$self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']);
$host_handle = $self['nickname'] . '.' . DI::baseUrl()->getHost();
$friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your Bluesky handle.', $host_handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $host_handle, $host_handle)];
$friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your AT Protocol handle.', $host_handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your AT Protocol handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $host_handle, $host_handle)];
if ($custom_handle) {
$handle = $host_handle;
}
@ -283,25 +286,31 @@ function bluesky_settings(array &$data)
$friendica_handle = [];
}
$web_frontend = ['' => 'System Default'];
foreach (DI::config()->get('atprotocol', 'frontends') as $key => $frontend) {
$web_frontend[$key] = $frontend[0];
}
$t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/bluesky/');
$html = Renderer::replaceMacros($t, [
'$enable' => ['bluesky', DI::l10n()->t('Enable Bluesky Post Addon'), $enabled],
'$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled],
'$enable' => ['bluesky', DI::l10n()->t('Enable AT Protocol Addon'), $enabled],
'$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post via AT Protocol by default'), $def_enabled],
'$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import],
'$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')],
'$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in AT Protocol.')],
'$complete_threads' => ['bluesky_complete_threads', DI::l10n()->t('Complete the threads'), $complete_threads, DI::l10n()->t('When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads.')],
'$custom_handle' => $friendica_handle,
'$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'],
'$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''],
'$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'],
'$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")],
'$handle' => ['bluesky_handle', DI::l10n()->t('AT Protocol handle'), $handle, '', '', $custom_handle ? 'readonly' : ''],
'$did' => ['bluesky_did', DI::l10n()->t('AT Protocol DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'],
'$password' => ['bluesky_password', DI::l10n()->t('AT Protocol app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the settings of your AT Protocol system.")],
'$web' => ['bluesky_web', DI::l10n()->t('Web front end'), $web, DI::l10n()->t('Choose your preferred external web front end for displaying posts and profiles.'), $web_frontend, ''],
'$status' => bluesky_get_status($handle, $did, $pds, $token),
]);
$data = [
'connector' => 'bluesky',
'title' => DI::l10n()->t('Bluesky Import/Export'),
'image' => 'images/bluesky.jpg',
'title' => DI::l10n()->t('AT Protocol (Bluesky, Eurosky, Blacksky, ...) Import/Export'),
'image' => 'images/500px-AT_Protocol_logo.png',
'enabled' => $enabled,
'html' => $html,
];
@ -331,7 +340,7 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p
switch ($status) {
case ATProtocol::STATUS_TOKEN_OK:
return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored.");
return DI::l10n()->t("You are authenticated to the AT Protocol PDS. For security reasons the password isn't stored.");
case ATProtocol::STATUS_SUCCESS:
return DI::l10n()->t('The communication with the personal data server service (PDS) is established.');
case ATProtocol::STATUS_API_FAIL;
@ -353,6 +362,8 @@ function bluesky_settings_post(array &$b)
return;
}
DI::atProtocol()->setApiForUser(DI::userSession()->getLocalUserId());
$old_pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds');
$old_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle');
$old_did = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'did');
@ -366,6 +377,11 @@ function bluesky_settings_post(array &$b)
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds']));
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads']));
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false));
if ($_POST['bluesky_web'] <> '') {
DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'web', $_POST['bluesky_web']);
} else {
DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'web');
}
if (!empty($handle)) {
$did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle);
@ -404,7 +420,7 @@ function bluesky_jot_nets(array &$jotnets_fields)
'type' => 'checkbox',
'field' => [
'bluesky_enable',
DI::l10n()->t('Post to Bluesky'),
DI::l10n()->t('Post via the AT Protocol'),
DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default')
]
];
@ -423,11 +439,11 @@ function bluesky_cron()
if ($last) {
$next = $last + ($poll_interval * 60);
if ($next > time()) {
Logger::notice('poll interval not reached');
DI::logger()->notice('poll interval not reached');
return;
}
}
Logger::notice('cron_start');
DI::logger()->notice('cron_start');
$abandon_days = intval(DI::config()->get('system', 'account_abandon_days'));
if ($abandon_days < 1) {
@ -438,20 +454,22 @@ function bluesky_cron()
$pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']);
foreach ($pconfigs as $pconfig) {
DI::atProtocol()->setApiForUser($pconfig['uid']);
if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) {
Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]);
DI::logger()->debug('User has got no valid DID', ['uid' => $pconfig['uid']]);
continue;
}
if ($abandon_days != 0) {
if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) {
Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]);
DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]);
continue;
}
}
// Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers
Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]);
DI::logger()->debug('Refresh the token', ['uid' => $pconfig['uid']]);
DI::atProtocol()->getUserToken($pconfig['uid']);
$last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync');
@ -465,32 +483,32 @@ function bluesky_cron()
Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']);
}
if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) {
Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]);
DI::logger()->debug('Fetch feeds for user', ['uid' => $pconfig['uid']]);
$feeds = bluesky_get_feeds($pconfig['uid']);
foreach ($feeds as $feed) {
Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed);
}
}
Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]);
DI::logger()->debug('Polling done for user', ['uid' => $pconfig['uid']]);
}
Logger::notice('Polling done for all users');
DI::logger()->notice('Polling done for all users');
DI::keyValue()->set('bluesky_last_poll', time());
$last_clean = DI::keyValue()->get('bluesky_last_clean');
if (empty($last_clean) || ($last_clean + 86400 < time())) {
Logger::notice('Start contact cleanup');
$contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::BLUESKY, 0, Contact::NOTHING]);
DI::logger()->notice('Start contact cleanup');
$contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::ATPROTO, 0, Contact::NOTHING]);
while ($contact = DBA::fetch($contacts)) {
Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0);
}
DBA::close($contacts);
DI::keyValue()->set('bluesky_last_clean', time());
Logger::notice('Contact cleanup done');
DI::logger()->notice('Contact cleanup done');
}
Logger::notice('cron_end');
DI::logger()->notice('cron_end');
}
function bluesky_hook_fork(array &$b)
@ -508,9 +526,9 @@ function bluesky_hook_fork(array &$b)
}
if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) {
// Don't post if it isn't a reply to a bluesky post
if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) {
Logger::notice('No bluesky parent found', ['item' => $post['id']]);
// Don't post if it isn't a reply to an AT Protocol post
if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::ATPROTO])) {
DI::logger()->notice('No AT Protocol parent found', ['item' => $post['id']]);
$b['execute'] = false;
return;
}
@ -552,17 +570,23 @@ function bluesky_post_local(array &$b)
function bluesky_send(array &$b)
{
DI::atProtocol()->setApiForUser($b['uid']);
if (($b['created'] !== $b['edited']) && !$b['deleted']) {
return;
}
if (Item::isGroupPost($b['uri-id'])) {
return;
}
if ($b['gravity'] != Item::GRAVITY_PARENT) {
Logger::debug('Got comment', ['item' => $b]);
DI::logger()->debug('Got comment', ['item' => $b]);
if ($b['deleted']) {
$uri = DI::atpProcessor()->getUriClass($b['uri']);
if (empty($uri)) {
Logger::debug('Not a bluesky post', ['uri' => $b['uri']]);
DI::logger()->debug('Not an AT Protocol post', ['uri' => $b['uri']]);
return;
}
bluesky_delete_post($b['uri'], $b['uid']);
@ -573,12 +597,12 @@ function bluesky_send(array &$b)
$parent = DI::atpProcessor()->getUriClass($b['thr-parent']);
if (empty($root) || empty($parent)) {
Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]);
DI::logger()->debug('No AT Protocol post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]);
return;
}
if ($b['gravity'] == Item::GRAVITY_COMMENT) {
Logger::debug('Posting comment', ['root' => $root, 'parent' => $parent]);
DI::logger()->debug('Posting comment', ['root' => $root, 'parent' => $parent]);
bluesky_create_post($b, $root, $parent);
return;
} elseif (in_array($b['verb'], [Activity::LIKE, Activity::ANNOUNCE])) {
@ -592,9 +616,11 @@ function bluesky_send(array &$b)
bluesky_create_post($b);
}
function bluesky_create_activity(array $item, stdClass $parent = null)
function bluesky_create_activity(array $item, ?stdClass $parent = null)
{
$uid = $item['uid'];
DI::atProtocol()->setApiForUser($uid);
$token = DI::atProtocol()->getUserToken($uid);
if (empty($token)) {
return;
@ -605,6 +631,8 @@ function bluesky_create_activity(array $item, stdClass $parent = null)
return;
}
$post = [];
if ($item['verb'] == Activity::LIKE) {
$record = [
'subject' => $parent,
@ -635,15 +663,17 @@ function bluesky_create_activity(array $item, stdClass $parent = null)
if (empty($activity->uri)) {
return;
}
Logger::debug('Activity done', ['return' => $activity]);
DI::logger()->debug('Activity done', ['return' => $activity]);
$uri = DI::atpProcessor()->getUri($activity);
Item::update(['extid' => $uri], ['guid' => $item['guid']]);
Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]);
DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $activity]);
}
function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null)
{
$uid = $item['uid'];
DI::atProtocol()->setApiForUser($uid);
$token = DI::atProtocol()->getUserToken($uid);
if (empty($token)) {
return;
@ -673,10 +703,12 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren
}
}
$item['body'] = bluesky_set_mentions($item['body']);
$urls = bluesky_get_urls($item['body']);
$item['body'] = $urls['body'];
$msg = Plaintext::getPost($item, 300, false, BBCode::BLUESKY);
$msg = Plaintext::getPost($item, 300, false, BBCode::ATPROTOCOL);
foreach ($msg['parts'] as $key => $part) {
$facets = bluesky_get_facets($part, $urls['urls']);
@ -722,26 +754,53 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren
}
return;
}
Logger::debug('Posting done', ['return' => $parent]);
DI::logger()->debug('Posting done', ['return' => $parent]);
if (empty($root)) {
$root = $parent;
}
if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) {
$uri = DI::atpProcessor()->getUri($parent);
Item::update(['extid' => $uri], ['guid' => $item['guid']]);
Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]);
DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $uri]);
}
}
}
function bluesky_get_urls(string $body): array
function bluesky_set_mentions(string $body): string
{
// Remove all hashtag and mention links
// Remove all url based mention links
$body = preg_replace("/([@!])\[url\=(.*?)\](.*?)\[\/url\]/ism", '$1$3', $body);
if (!preg_match_all("/[@!]\[url\=(did:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) {
return $body;
}
foreach ($matches as $match) {
$contact = Contact::selectFirst(['addr'], ['nurl' => $match[1]]);
if (!empty($contact['addr'])) {
$body = str_replace($match[0], '@[url=' . $match[1] . ']' . $contact['addr'] . '[/url]', $body);
} else {
$body = str_replace($match[0], '@' . $match[2], $body);
}
}
return $body;
}
function bluesky_get_urls(string $body): array
{
$body = BBCode::expandVideoLinks($body);
$urls = [];
// Search for Mentions
if (preg_match_all("/[@!]\[url\=(did:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
$text = '@' . $match[2];
$urls[strpos($body, $match[0])] = ['mention' => $match[1], 'text' => $text, 'hash' => $text];
$body = str_replace($match[0], $text, $body);
}
}
// Search for hash tags
if (preg_match_all("/#\[url\=(https?:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
@ -826,6 +885,9 @@ function bluesky_get_facets(string $body, array $urls): array
} elseif (!empty($url['url'])) {
$feature->uri = $url['url'];
$feature->$type = 'app.bsky.richtext.facet#link';
} elseif (!empty($url['mention'])) {
$feature->did = $url['mention'];
$feature->$type = 'app.bsky.richtext.facet#mention';
} else {
continue;
}
@ -899,20 +961,20 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass
$new_size = strlen($content);
if (($size != 0) && ($new_size == 0) && ($retrial == 0)) {
Logger::warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
DI::logger()->warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
$content = Photo::getImageForPhoto($photo);
} else {
Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
}
$data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]);
if (empty($data) || empty($data->blob)) {
Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
DI::logger()->info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
return null;
}
Item::incrementOutbound(Protocol::BLUESKY);
Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
Item::incrementOutbound(Protocol::ATPROTO);
DI::logger()->debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]);
return $data->blob;
}
@ -920,15 +982,17 @@ function bluesky_delete_post(string $uri, int $uid)
{
$parts = DI::atpProcessor()->getUriParts($uri);
if (empty($parts)) {
Logger::debug('No uri delected', ['uri' => $uri]);
DI::logger()->debug('No uri delected', ['uri' => $uri]);
return;
}
DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts);
Logger::debug('Deleted', ['parts' => $parts]);
DI::logger()->debug('Deleted', ['parts' => $parts]);
}
function bluesky_fetch_timeline(int $uid)
{
DI::atProtocol()->setApiForUser($uid);
$data = DI::atProtocol()->XRPCGet('app.bsky.feed.getTimeline', [], $uid);
if (empty($data)) {
return;
@ -967,7 +1031,7 @@ function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $
}
if ($complete) {
$uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true, $protocol);
$uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', false, $protocol);
$uri_id = DI::atpProcessor()->fetchUriId($uri, $uid);
} else {
$uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol);
@ -985,7 +1049,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid)
$contact = DI::atpActor()->getContactByDID($reason->by->did, $uid, 0);
$item = [
'network' => Protocol::BLUESKY,
'network' => Protocol::ATPROTO,
'protocol' => Conversation::PARCEL_CONNECTOR,
'uid' => $uid,
'wall' => false,
@ -1006,6 +1070,10 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid)
return;
}
if (Post::exists(['uid' => $item['uid'], 'thr-parent' => $item['thr-parent'], 'verb' => $item['verb'], 'contact-id' => $item['contact-id']])) {
return;
}
$item['guid'] = Item::guidFromUri($item['uri'], $contact['alias']);
$item['owner-name'] = $item['author-name'];
$item['owner-link'] = $item['author-link'];
@ -1018,6 +1086,8 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid)
function bluesky_fetch_notifications(int $uid)
{
DI::atProtocol()->setApiForUser($uid);
$data = DI::atProtocol()->XRPCGet('app.bsky.notification.listNotifications', [], $uid);
if (empty($data->notifications)) {
return;
@ -1026,22 +1096,22 @@ function bluesky_fetch_notifications(int $uid)
foreach ($data->notifications as $notification) {
$uri = DI::atpProcessor()->getUri($notification);
if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) {
Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]);
DI::logger()->debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]);
continue;
}
Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]);
DI::logger()->debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]);
switch ($notification->reason) {
case 'like':
$item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR);
$item['gravity'] = Item::GRAVITY_ACTIVITY;
$item['body'] = $item['verb'] = Activity::LIKE;
$item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject);
$item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0);
$item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0, '', false, Conversation::PARCEL_CONNECTOR);
if (!empty($item['thr-parent'])) {
$data = Item::insert($item);
Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]);
DI::logger()->debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]);
} else {
Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]);
DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]);
}
break;
@ -1050,40 +1120,40 @@ function bluesky_fetch_notifications(int $uid)
$item['gravity'] = Item::GRAVITY_ACTIVITY;
$item['body'] = $item['verb'] = Activity::ANNOUNCE;
$item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject);
$item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0);
$item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0, '', false, Conversation::PARCEL_CONNECTOR);
if (!empty($item['thr-parent'])) {
$data = Item::insert($item);
Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]);
DI::logger()->debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]);
} else {
Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]);
DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]);
}
break;
case 'follow':
$contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid);
Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]);
DI::logger()->debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]);
break;
case 'mention':
$contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0);
Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0, '', false, Conversation::PARCEL_CONNECTOR);
DI::logger()->debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
break;
case 'reply':
$contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0);
Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0, '', false, Conversation::PARCEL_CONNECTOR);
DI::logger()->debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
break;
case 'quote':
$contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0);
Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
$result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0, '', false, Conversation::PARCEL_CONNECTOR);
DI::logger()->debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]);
break;
default:
Logger::notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]);
DI::logger()->notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]);
break;
}
}
@ -1091,6 +1161,8 @@ function bluesky_fetch_notifications(int $uid)
function bluesky_fetch_feed(int $uid, string $feed)
{
DI::atProtocol()->setApiForUser($uid);
$data = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeed', ['feed' => $feed], $uid);
if (empty($data)) {
return;
@ -1114,16 +1186,16 @@ function bluesky_fetch_feed(int $uid, string $feed)
$languages = $entry->post->record->langs ?? [];
if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) {
Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]);
DI::logger()->debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]);
continue;
}
$causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0);
$uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR);
if (!empty($uri_id)) {
$stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl);
Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]);
DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]);
} else {
Logger::notice('Post not found', ['entry' => $entry]);
DI::logger()->notice('Post not found', ['entry' => $entry]);
}
if (!empty($entry->reason)) {
bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid);
@ -1139,8 +1211,14 @@ function bluesky_get_feeds(int $uid): array
return [];
}
foreach ($preferences->preferences as $preference) {
if ($preference->$type == 'app.bsky.actor.defs#savedFeedsPref') {
return $preference->pinned ?? [];
if ($preference->$type == 'app.bsky.actor.defs#savedFeedsPrefV2') {
$pinned = [];
foreach ($preference->items as $item) {
if (($item->type == 'feed') && $item->pinned) {
$pinned[] = $item->value;
}
}
return $pinned;
}
}
return [];

View file

@ -1,6 +1,6 @@
<?php
use Friendica\Core\Logger;
use Friendica\DI;
function bluesky_feed_run($argv, $argc)
{
@ -10,7 +10,7 @@ function bluesky_feed_run($argv, $argc)
return;
}
Logger::debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]);
DI::logger()->debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]);
bluesky_fetch_feed($argv[1], $argv[2]);
Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]);
DI::logger()->debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]);
}

View file

@ -1,6 +1,6 @@
<?php
use Friendica\Core\Logger;
use Friendica\DI;
function bluesky_notifications_run($argv, $argc)
{
@ -10,7 +10,7 @@ function bluesky_notifications_run($argv, $argc)
return;
}
Logger::notice('importing notifications - start', ['user' => $argv[1]]);
DI::logger()->notice('importing notifications - start', ['user' => $argv[1]]);
bluesky_fetch_notifications($argv[1]);
Logger::notice('importing notifications - done', ['user' => $argv[1]]);
DI::logger()->notice('importing notifications - done', ['user' => $argv[1]]);
}

View file

@ -1,6 +1,6 @@
<?php
use Friendica\Core\Logger;
use Friendica\DI;
function bluesky_timeline_run($argv, $argc)
{
@ -10,7 +10,7 @@ function bluesky_timeline_run($argv, $argc)
return;
}
Logger::notice('importing timeline - start', ['user' => $argv[1]]);
DI::logger()->notice('importing timeline - start', ['user' => $argv[1]]);
bluesky_fetch_timeline($argv[1]);
Logger::notice('importing timeline - done', ['user' => $argv[1]]);
DI::logger()->notice('importing timeline - done', ['user' => $argv[1]]);
}

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-29 18:16+0000\n"
"POT-Creation-Date: 2026-03-18 13:20+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,117 +17,126 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: bluesky.php:335
#: bluesky.php:248
msgid "Save Settings"
msgstr ""
#: bluesky.php:336
msgid "Allow your users to use your hostname for their Bluesky handles"
#: bluesky.php:249
msgid "Allow your users to use your hostname for their AT Protocol handles"
msgstr ""
#: bluesky.php:336
#: bluesky.php:249
#, php-format
msgid "Before enabling this option, you have to setup a wildcard domain configuration and you have to enable wildcard requests in your webserver configuration. On Apache this is done by adding \"ServerAlias *.%s\" to your HTTP configuration. You don't need to change the HTTPS configuration."
msgstr ""
#: bluesky.php:365
#: bluesky.php:281
#, php-format
msgid "Allow to use %s as your Bluesky handle."
msgid "Allow to use %s as your AT Protocol handle."
msgstr ""
#: bluesky.php:365
#: bluesky.php:281
#, php-format
msgid "When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select \"No DNS Panel\". Then select \"Verify Text File\"."
msgid "When enabled, you can use %s as your AT Protocol handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select \"No DNS Panel\". Then select \"Verify Text File\"."
msgstr ""
#: bluesky.php:375
msgid "Enable Bluesky Post Addon"
#: bluesky.php:298
msgid "Enable AT Protocol Addon"
msgstr ""
#: bluesky.php:376
msgid "Post to Bluesky by default"
#: bluesky.php:299
msgid "Post via AT Protocol by default"
msgstr ""
#: bluesky.php:377
#: bluesky.php:300
msgid "Import the remote timeline"
msgstr ""
#: bluesky.php:378
#: bluesky.php:301
msgid "Import the pinned feeds"
msgstr ""
#: bluesky.php:378
msgid "When activated, Posts will be imported from all the feeds that you pinned in Bluesky."
#: bluesky.php:301
msgid "When activated, Posts will be imported from all the feeds that you pinned in AT Protocol."
msgstr ""
#: bluesky.php:379
#: bluesky.php:302
msgid "Complete the threads"
msgstr ""
#: bluesky.php:379
#: bluesky.php:302
msgid "When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads."
msgstr ""
#: bluesky.php:381
#: bluesky.php:304
msgid "Personal Data Server"
msgstr ""
#: bluesky.php:381
#: bluesky.php:304
msgid "The personal data server (PDS) is the system that hosts your profile."
msgstr ""
#: bluesky.php:382
msgid "Bluesky handle"
#: bluesky.php:305
msgid "AT Protocol handle"
msgstr ""
#: bluesky.php:383
msgid "Bluesky DID"
#: bluesky.php:306
msgid "AT Protocol DID"
msgstr ""
#: bluesky.php:383
#: bluesky.php:306
msgid "This is the unique identifier. It will be fetched automatically, when the handle is entered."
msgstr ""
#: bluesky.php:384
msgid "Bluesky app password"
#: bluesky.php:307
msgid "AT Protocol app password"
msgstr ""
#: bluesky.php:384
msgid "Please don't add your real password here, but instead create a specific app password in the Bluesky settings."
#: bluesky.php:307
msgid "Please don't add your real password here, but instead create a specific app password in the settings of your AT Protocol system."
msgstr ""
#: bluesky.php:390
msgid "Bluesky Import/Export"
#: bluesky.php:308
msgid "Web front end"
msgstr ""
#: bluesky.php:400
#: bluesky.php:308
msgid "Choose your preferred external web front end for displaying posts and profiles."
msgstr ""
#: bluesky.php:314
msgid "AT Protocol (Bluesky, Eurosky, Blacksky, ...) Import/Export"
msgstr ""
#: bluesky.php:324
msgid "You are not authenticated. Please enter your handle and the app password."
msgstr ""
#: bluesky.php:420
msgid "You are authenticated to Bluesky. For security reasons the password isn't stored."
#: bluesky.php:345
msgid "You are authenticated to the AT Protocol PDS. For security reasons the password isn't stored."
msgstr ""
#: bluesky.php:422
#: bluesky.php:347
msgid "The communication with the personal data server service (PDS) is established."
msgstr ""
#: bluesky.php:424
msgid "Communication issues with the personal data server service (PDS)."
#: bluesky.php:349
#, php-format
msgid "Communication issues with the personal data server service (PDS): %s"
msgstr ""
#: bluesky.php:426
#: bluesky.php:351
msgid "The DID for the provided handle could not be detected. Please check if you entered the correct handle."
msgstr ""
#: bluesky.php:428
#: bluesky.php:353
msgid "The personal data server service (PDS) could not be detected."
msgstr ""
#: bluesky.php:430
#: bluesky.php:355
msgid "The authentication with the provided handle and password failed. Please check if you entered the correct password."
msgstr ""
#: bluesky.php:492
msgid "Post to Bluesky"
#: bluesky.php:425
msgid "Post via the AT Protocol"
msgstr ""

View file

@ -10,4 +10,5 @@
{{include file="field_input.tpl" field=$pds}}
{{include file="field_input.tpl" field=$handle}}
{{include file="field_input.tpl" field=$did}}
{{include file="field_input.tpl" field=$password}}
{{include file="field_input.tpl" field=$password}}
{{include file="field_select.tpl" field=$web}}

View file

@ -6,7 +6,6 @@
* Author: Mike Macgirvin <mike@macgirvin.com>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\DI;

View file

@ -0,0 +1,23 @@
# ADDON buglink
# Copyright (C)
# This file is distributed under the same license as the Friendica buglink addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: buglink.php:20
msgid "Report Bug"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,23 @@
# ADDON buglink
# Copyright (C)
# This file is distributed under the same license as the Friendica buglink addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: buglink.php:20
msgid "Report Bug"
msgstr ""

View file

@ -1,3 +1,7 @@
<?php
$a->strings["Report Bug"] = "Skribi cimraporton";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,23 @@
# ADDON buglink
# Copyright (C)
# This file is distributed under the same license as the Friendica buglink addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 11:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: buglink.php:20
msgid "Report Bug"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -6,7 +6,6 @@
* Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\DI;
@ -16,7 +15,7 @@ function calc_install() {
function calc_app_menu(array &$b)
{
$b['app_menu'][] = '<div class="app-title"><a href="calc">Calculator</a></div>';
$b['app_menu'][] = '<div class="app-title"><a href="calc">Calculator</a></div>';
}
/**
@ -296,7 +295,7 @@ $o .= <<< EOT
<h3>Calculator</h3>
<br /><br />
<table>
<tbody><tr><td>
<tbody><tr><td>
<table bgcolor="#af9999" border="1">
<tbody><tr><td>
<table border="1" cellpadding="2" cellspacing="2">
@ -323,7 +322,7 @@ $o .= <<< EOT
<td><input name="multiplication" value="&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;" onclick="multiplyNumbers()" type="button"></td>
</tr><tr align="left" valign="middle">
<td><input name="zero" value="&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;" onclick="addDisplay(0)" type="button"></td>
<td><input name="pi" value="&nbsp;Pi&nbsp;&nbsp;" onclick="addDisplay(Math.PI)" type="button"> </td>
<td><input name="pi" value="&nbsp;Pi&nbsp;&nbsp;" onclick="addDisplay(Math.PI)" type="button"> </td>
<td><input name="dot" value="&nbsp;&nbsp;&nbsp;.&nbsp;&nbsp;&nbsp;" onclick='addDisplay(".")' type="button"></td>
<td><input name="division" value="&nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;" onclick="divideNumbers()" type="button"></td>
</tr><tr align="left" valign="middle">
@ -345,13 +344,13 @@ $o .= <<< EOT
</form>
<!--
<TD VALIGN=top>
<TD VALIGN=top>
<B>NOTE:</B> All sine and cosine calculations are
<br>done in radians. Remember to convert first
<br>if using degrees.
</TD>
-->
</td></tr></tbody></table>

View file

@ -6,11 +6,8 @@
* Author: Fabio <https://kirgroup.com/profile/fabrixxm>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
@ -29,7 +26,7 @@ function catavatar_install()
Hook::register('addon_settings', __FILE__, 'catavatar_addon_settings');
Hook::register('addon_settings_post', __FILE__, 'catavatar_addon_settings_post');
Logger::notice('registered catavatar');
DI::logger()->notice('registered catavatar');
}
/**

View file

@ -0,0 +1,54 @@
# ADDON catavatar
# Copyright (C)
# This file is distributed under the same license as the Friendica catavatar addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2018-04-07 05:23+0000\n"
"Language-Team: Bulgarian (https://app.transifex.com/Friendica/teams/12172/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: catavatar.php:48
msgid "Set default profile avatar or randomize the cat."
msgstr ""
#: catavatar.php:53
msgid "Cat Avatar Settings"
msgstr ""
#: catavatar.php:56
msgid "Use Cat as Avatar"
msgstr ""
#: catavatar.php:57
msgid "Another random Cat!"
msgstr ""
#: catavatar.php:58
msgid "Reset to email Cat"
msgstr ""
#: catavatar.php:77
msgid "The cat hadn't found itself."
msgstr ""
#: catavatar.php:86
msgid "There was an error, the cat ran away."
msgstr ""
#: catavatar.php:92
msgid "Profile Photos"
msgstr ""
#: catavatar.php:102
msgid "Meow!"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,54 @@
# ADDON catavatar
# Copyright (C)
# This file is distributed under the same license as the Friendica catavatar addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2018-04-07 05:23+0000\n"
"Language-Team: Esperanto (https://app.transifex.com/Friendica/teams/12172/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: catavatar.php:48
msgid "Set default profile avatar or randomize the cat."
msgstr ""
#: catavatar.php:53
msgid "Cat Avatar Settings"
msgstr ""
#: catavatar.php:56
msgid "Use Cat as Avatar"
msgstr ""
#: catavatar.php:57
msgid "Another random Cat!"
msgstr ""
#: catavatar.php:58
msgid "Reset to email Cat"
msgstr ""
#: catavatar.php:77
msgid "The cat hadn't found itself."
msgstr ""
#: catavatar.php:86
msgid "There was an error, the cat ran away."
msgstr ""
#: catavatar.php:92
msgid "Profile Photos"
msgstr ""
#: catavatar.php:102
msgid "Meow!"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,54 @@
# ADDON catavatar
# Copyright (C)
# This file is distributed under the same license as the Friendica catavatar addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2018-04-07 05:23+0000\n"
"Language-Team: Estonian (https://app.transifex.com/Friendica/teams/12172/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: catavatar.php:48
msgid "Set default profile avatar or randomize the cat."
msgstr ""
#: catavatar.php:53
msgid "Cat Avatar Settings"
msgstr ""
#: catavatar.php:56
msgid "Use Cat as Avatar"
msgstr ""
#: catavatar.php:57
msgid "Another random Cat!"
msgstr ""
#: catavatar.php:58
msgid "Reset to email Cat"
msgstr ""
#: catavatar.php:77
msgid "The cat hadn't found itself."
msgstr ""
#: catavatar.php:86
msgid "There was an error, the cat ran away."
msgstr ""
#: catavatar.php:92
msgid "Profile Photos"
msgstr ""
#: catavatar.php:102
msgid "Meow!"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,54 @@
# ADDON catavatar
# Copyright (C)
# This file is distributed under the same license as the Friendica catavatar addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2018-04-07 05:23+0000\n"
"Language-Team: Gaelic, Scottish (https://app.transifex.com/Friendica/teams/12172/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: catavatar.php:48
msgid "Set default profile avatar or randomize the cat."
msgstr ""
#: catavatar.php:53
msgid "Cat Avatar Settings"
msgstr ""
#: catavatar.php:56
msgid "Use Cat as Avatar"
msgstr ""
#: catavatar.php:57
msgid "Another random Cat!"
msgstr ""
#: catavatar.php:58
msgid "Reset to email Cat"
msgstr ""
#: catavatar.php:77
msgid "The cat hadn't found itself."
msgstr ""
#: catavatar.php:86
msgid "There was an error, the cat ran away."
msgstr ""
#: catavatar.php:92
msgid "Profile Photos"
msgstr ""
#: catavatar.php:102
msgid "Meow!"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -7,7 +7,6 @@
*/
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\DI;
function cld_install()
@ -18,7 +17,17 @@ function cld_install()
function cld_detect_languages(array &$data)
{
if (!in_array('cld2', get_loaded_extensions())) {
Logger::warning('CLD2 is not installed.');
DI::logger()->warning('CLD2 is not installed.');
return;
}
if (!class_exists('CLD2Detector')) {
DI::logger()->warning('CLD2Detector class does not exist.');
return;
}
if (!class_exists('CLD2Encoding')) {
DI::logger()->warning('CLD2Encoding class does not exist.');
return;
}
@ -43,7 +52,7 @@ function cld_detect_languages(array &$data)
}
if (!$result['is_reliable']) {
Logger::debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
DI::logger()->debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
if (($original == $detected) && ($data['detected'][$original] < $result['language_probability'] / 100)) {
$data['detected'][$original] = $result['language_probability'] / 100;
}
@ -53,12 +62,12 @@ function cld_detect_languages(array &$data)
$available = array_keys(DI::l10n()->getLanguageCodes());
if (!in_array($detected, $available)) {
Logger::debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
DI::logger()->debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
return;
}
if ($original != $detected) {
Logger::debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
DI::logger()->debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]);
}
$length = count($data['detected']);

View file

@ -169,7 +169,6 @@ class UnitConvertor
* @param string name of the source unit from which to convert
* @param string name of the target unit to which we are converting
* @param integer double precision of the end result
* @return void
* @access public
*/
function convert($value, $from_unit, $to_unit, $precision)
@ -280,4 +279,4 @@ class UnitConvertor
} // end func getConvSpecs
} // end class UnitConvertor
?>
?>

View file

@ -6,7 +6,6 @@
* Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
*/
use Friendica\App;
use Friendica\Core\Hook;
function convert_install() {
@ -26,7 +25,7 @@ function convert_content() {
// @TODO Let's one day rewrite this to a modern composer package
include 'UnitConvertor.php';
class TP_Converter extends UnitConvertor
$conv = new class('en') extends UnitConvertor
{
public function __construct(string $lang = 'en')
{
@ -43,7 +42,7 @@ function convert_content() {
private function findBaseUnit($from, $to)
{
while (list($skey, $sval) = each($this->bases)) {
foreach ($this->bases as $skey => $sval) {
if ($skey == $from || $to == $skey || in_array($to, $sval) || in_array($from, $sval)) {
return $skey;
}
@ -63,7 +62,7 @@ function convert_content() {
$cells[] = $cell;
// We now have the base unit and value now lets produce the table;
while (list($key, $val) = each($this->bases[$base_unit])) {
foreach ($this->bases[$base_unit] as $val) {
$cell ['value'] = $this->convert($value, $from_unit, $val, $precision) . ' ' . $val;
$cell ['class'] = ($val == $from_unit || $val == $to_unit) ? 'framedred' : '';
$cells[] = $cell;
@ -86,9 +85,7 @@ function convert_content() {
return $string;
}
}
$conv = new TP_Converter('en');
};
$conversions = [
'Temperature' => ['base' => 'Celsius',
@ -176,15 +173,15 @@ function convert_content() {
]
];
while (list($key, $val) = each($conversions)) {
foreach ($conversions as $key => $val) {
$conv->addConversion($val['base'], $val['conv']);
$list[$key][] = $val['base'];
while (list($ukey, $uval) = each($val['conv'])) {
foreach ($val['conv'] as $ukey => $uval) {
$list[$key][] = $ukey;
}
}
$o .= '<h3>Unit Conversions</h3>';
$o = '<h3>Unit Conversions</h3>';
if (isset($_POST['from_unit']) && isset($_POST['value'])) {
$o .= ($conv->getTable(intval($_POST['value']), $_POST['from_unit'], $_POST['to_unit'], 5)) . '</p>';
@ -202,10 +199,9 @@ function convert_content() {
$o .= '<input name="value" type="text" id="value" value="' . $value . '" size="10" maxlength="10" />';
$o .= '<select name="from_unit" size="12">';
reset($list);
while(list($key, $val) = each($list)) {
foreach ($list as $key => $val) {
$o .= "\n\t<optgroup label=\"$key\">";
while(list($ukey, $uval) = each($val)) {
foreach ($val as $ukey => $uval) {
$selected = (($uval == $_POST['from_unit']) ? ' selected="selected" ' : '');
$o .= "\n\t\t<option value=\"$uval\" $selected >$uval</option>";
}

View file

@ -7,7 +7,6 @@
* Author: Peter Liebetrau <https://socivitas/profile/peerteer>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Renderer;
use Friendica\DI;

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Bulgarian (https://app.transifex.com/Friendica/teams/12172/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Esperanto (https://app.transifex.com/Friendica/teams/12172/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Estonian (https://app.transifex.com/Friendica/teams/12172/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -6,6 +6,7 @@
# Translators:
# Vladimir Núñez <lapoubelle111@gmail.com>, 2019
# bob lebonche <lebonche@tutanota.com>, 2021
# cracrayol, 2025
#
#, fuzzy
msgid ""
@ -14,8 +15,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Last-Translator: bob lebonche <lebonche@tutanota.com>, 2021\n"
"Language-Team: French (https://www.transifex.com/Friendica/teams/12172/fr/)\n"
"Last-Translator: cracrayol, 2025\n"
"Language-Team: French (https://app.transifex.com/Friendica/teams/12172/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -55,7 +56,7 @@ msgstr "Bouton OK Texte "
#: cookienotice.php:50
msgid "Save Settings"
msgstr "Sauvegarder les réglages"
msgstr "Sauvegarder les paramètres "
#: cookienotice.php:107
msgid ""
@ -63,5 +64,5 @@ msgid ""
"accept the usage of these cookies by continue browsing this website."
msgstr ""
"Ce site utilise des cookies pour reconnaître les visiteurs et les "
"utilisateurs connectés. Vous accepter l'utilisation de ces cookies en "
"utilisateurs connectés. Vous acceptez l'utilisation de ces cookies en "
"continuant sur ce site."

View file

@ -10,5 +10,5 @@ $a->strings['OK'] = 'Ok';
$a->strings['<b>Configure your cookie usage notice.</b> It should just be a notice, saying that the website uses cookies. It is shown as long as a user didnt confirm clicking the OK button.'] = '<b>Configurez votre politique d\'utilisation des cookies.</b> Cela devrait juste être un avertissement, signalant l\'utilisation de cookies par le site. Cela sera affiché tant que l\'utilisateur n\'aura pas confirmé en cliquant sur le bouton OK.';
$a->strings['Cookie Usage Notice'] = 'Politique d\'utilisation des cookies.';
$a->strings['OK Button Text'] = 'Bouton OK Texte ';
$a->strings['Save Settings'] = 'Sauvegarder les réglages';
$a->strings['This website uses cookies to recognize revisiting and logged in users. You accept the usage of these cookies by continue browsing this website.'] = 'Ce site utilise des cookies pour reconnaître les visiteurs et les utilisateurs connectés. Vous accepter l\'utilisation de ces cookies en continuant sur ce site.';
$a->strings['Save Settings'] = 'Sauvegarder les paramètres ';
$a->strings['This website uses cookies to recognize revisiting and logged in users. You accept the usage of these cookies by continue browsing this website.'] = 'Ce site utilise des cookies pour reconnaître les visiteurs et les utilisateurs connectés. Vous acceptez l\'utilisation de ces cookies en continuant sur ce site.';

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Gaelic, Scottish (https://app.transifex.com/Friendica/teams/12172/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Icelandic (https://app.transifex.com/Friendica/teams/12172/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -0,0 +1,53 @@
# ADDON cookienotice
# Copyright (C)
# This file is distributed under the same license as the Friendica cookienotice addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2019-01-23 16:01+0000\n"
"Language-Team: Russian (https://app.transifex.com/Friendica/teams/12172/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#: cookienotice.php:42
msgid ""
"This website uses cookies. If you continue browsing this website, you agree "
"to the usage of cookies."
msgstr ""
#: cookienotice.php:43 cookienotice.php:108
msgid "OK"
msgstr ""
#: cookienotice.php:47
msgid ""
"<b>Configure your cookie usage notice.</b> It should just be a notice, "
"saying that the website uses cookies. It is shown as long as a user didnt "
"confirm clicking the OK button."
msgstr ""
#: cookienotice.php:48
msgid "Cookie Usage Notice"
msgstr ""
#: cookienotice.php:49
msgid "OK Button Text"
msgstr ""
#: cookienotice.php:50
msgid "Save Settings"
msgstr ""
#: cookienotice.php:107
msgid ""
"This website uses cookies to recognize revisiting and logged in users. You "
"accept the usage of these cookies by continue browsing this website."
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_ru")) {
function string_plural_select_ru($n){
$n = intval($n);
if ($n%10==1 && $n%100!=11) { return 0; } else if ($n%10>=2 && $n%10<=4 && ($n%100<12 || $n%100>14)) { return 1; } else if ($n%10==0 || ($n%10>=5 && $n%10<=9) || ($n%100>=11 && $n%100<=14)) { return 2; } else { return 3; }
}}

View file

@ -29,10 +29,10 @@ function getWeather($loc, $units = 'metric', $lang = 'en', $appid = '', $cacheti
$now = new DateTime();
if (!is_null($cached)) {
$cdate = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'curweather', 'last');
$cdate = (int) DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'curweather', 'last');
$cached = unserialize($cached);
if ($cdate + $cachetime > $now->getTimestamp()) {
if ($cdate + (int) $cachetime > $now->getTimestamp()) {
return $cached;
}
}

View file

@ -0,0 +1,123 @@
# ADDON curweather
# Copyright (C)
# This file is distributed under the same license as the Friendica curweather addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 11:34+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: curweather.php:47
msgid "Error fetching weather data. Error was: "
msgstr ""
#: curweather.php:130
msgid "Current Weather"
msgstr ""
#: curweather.php:137
msgid "Relative Humidity"
msgstr ""
#: curweather.php:138
msgid "Pressure"
msgstr ""
#: curweather.php:139
msgid "Wind"
msgstr ""
#: curweather.php:140
msgid "Last Updated"
msgstr ""
#: curweather.php:141
msgid "Data by"
msgstr ""
#: curweather.php:142
msgid "Show on map"
msgstr ""
#: curweather.php:147
msgid "There was a problem accessing the weather data. But have a look"
msgstr ""
#: curweather.php:149
msgid "at OpenWeatherMap"
msgstr ""
#: curweather.php:178
msgid "No APPID found, please contact your admin to obtain one."
msgstr ""
#: curweather.php:188
msgid "Enter either the name of your location or the zip code."
msgstr ""
#: curweather.php:189
msgid "Your Location"
msgstr ""
#: curweather.php:189
msgid ""
"Identifier of your location (name or zip code), e.g. <em>Berlin,DE</em> or "
"<em>14476,DE</em>."
msgstr ""
#: curweather.php:190
msgid "Units"
msgstr ""
#: curweather.php:190
msgid "select if the temperature should be displayed in &deg;C or &deg;F"
msgstr ""
#: curweather.php:191
msgid "Show weather data"
msgstr ""
#: curweather.php:196
msgid "Current Weather Settings"
msgstr ""
#: curweather.php:227
msgid "Save Settings"
msgstr ""
#: curweather.php:230
msgid "Caching Interval"
msgstr ""
#: curweather.php:232
msgid ""
"For how long should the weather data be cached? Choose according your "
"OpenWeatherMap account type."
msgstr ""
#: curweather.php:233
msgid "no cache"
msgstr ""
#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237
msgid "minutes"
msgstr ""
#: curweather.php:240
msgid "Your APPID"
msgstr ""
#: curweather.php:240
msgid "Your API key provided by OpenWeatherMap"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,123 @@
# ADDON curweather
# Copyright (C)
# This file is distributed under the same license as the Friendica curweather addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 11:34+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: curweather.php:47
msgid "Error fetching weather data. Error was: "
msgstr ""
#: curweather.php:130
msgid "Current Weather"
msgstr ""
#: curweather.php:137
msgid "Relative Humidity"
msgstr ""
#: curweather.php:138
msgid "Pressure"
msgstr ""
#: curweather.php:139
msgid "Wind"
msgstr ""
#: curweather.php:140
msgid "Last Updated"
msgstr ""
#: curweather.php:141
msgid "Data by"
msgstr ""
#: curweather.php:142
msgid "Show on map"
msgstr ""
#: curweather.php:147
msgid "There was a problem accessing the weather data. But have a look"
msgstr ""
#: curweather.php:149
msgid "at OpenWeatherMap"
msgstr ""
#: curweather.php:178
msgid "No APPID found, please contact your admin to obtain one."
msgstr ""
#: curweather.php:188
msgid "Enter either the name of your location or the zip code."
msgstr ""
#: curweather.php:189
msgid "Your Location"
msgstr ""
#: curweather.php:189
msgid ""
"Identifier of your location (name or zip code), e.g. <em>Berlin,DE</em> or "
"<em>14476,DE</em>."
msgstr ""
#: curweather.php:190
msgid "Units"
msgstr ""
#: curweather.php:190
msgid "select if the temperature should be displayed in &deg;C or &deg;F"
msgstr ""
#: curweather.php:191
msgid "Show weather data"
msgstr ""
#: curweather.php:196
msgid "Current Weather Settings"
msgstr ""
#: curweather.php:227
msgid "Save Settings"
msgstr ""
#: curweather.php:230
msgid "Caching Interval"
msgstr ""
#: curweather.php:232
msgid ""
"For how long should the weather data be cached? Choose according your "
"OpenWeatherMap account type."
msgstr ""
#: curweather.php:233
msgid "no cache"
msgstr ""
#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237
msgid "minutes"
msgstr ""
#: curweather.php:240
msgid "Your APPID"
msgstr ""
#: curweather.php:240
msgid "Your API key provided by OpenWeatherMap"
msgstr ""

View file

@ -1,3 +1,7 @@
<?php
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,123 @@
# ADDON curweather
# Copyright (C)
# This file is distributed under the same license as the Friendica curweather addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 11:34+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: curweather.php:47
msgid "Error fetching weather data. Error was: "
msgstr ""
#: curweather.php:130
msgid "Current Weather"
msgstr ""
#: curweather.php:137
msgid "Relative Humidity"
msgstr ""
#: curweather.php:138
msgid "Pressure"
msgstr ""
#: curweather.php:139
msgid "Wind"
msgstr ""
#: curweather.php:140
msgid "Last Updated"
msgstr ""
#: curweather.php:141
msgid "Data by"
msgstr ""
#: curweather.php:142
msgid "Show on map"
msgstr ""
#: curweather.php:147
msgid "There was a problem accessing the weather data. But have a look"
msgstr ""
#: curweather.php:149
msgid "at OpenWeatherMap"
msgstr ""
#: curweather.php:178
msgid "No APPID found, please contact your admin to obtain one."
msgstr ""
#: curweather.php:188
msgid "Enter either the name of your location or the zip code."
msgstr ""
#: curweather.php:189
msgid "Your Location"
msgstr ""
#: curweather.php:189
msgid ""
"Identifier of your location (name or zip code), e.g. <em>Berlin,DE</em> or "
"<em>14476,DE</em>."
msgstr ""
#: curweather.php:190
msgid "Units"
msgstr ""
#: curweather.php:190
msgid "select if the temperature should be displayed in &deg;C or &deg;F"
msgstr ""
#: curweather.php:191
msgid "Show weather data"
msgstr ""
#: curweather.php:196
msgid "Current Weather Settings"
msgstr ""
#: curweather.php:227
msgid "Save Settings"
msgstr ""
#: curweather.php:230
msgid "Caching Interval"
msgstr ""
#: curweather.php:232
msgid ""
"For how long should the weather data be cached? Choose according your "
"OpenWeatherMap account type."
msgstr ""
#: curweather.php:233
msgid "no cache"
msgstr ""
#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237
msgid "minutes"
msgstr ""
#: curweather.php:240
msgid "Your APPID"
msgstr ""
#: curweather.php:240
msgid "Your API key provided by OpenWeatherMap"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,123 @@
# ADDON curweather
# Copyright (C)
# This file is distributed under the same license as the Friendica curweather addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 11:34+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: curweather.php:47
msgid "Error fetching weather data. Error was: "
msgstr ""
#: curweather.php:130
msgid "Current Weather"
msgstr ""
#: curweather.php:137
msgid "Relative Humidity"
msgstr ""
#: curweather.php:138
msgid "Pressure"
msgstr ""
#: curweather.php:139
msgid "Wind"
msgstr ""
#: curweather.php:140
msgid "Last Updated"
msgstr ""
#: curweather.php:141
msgid "Data by"
msgstr ""
#: curweather.php:142
msgid "Show on map"
msgstr ""
#: curweather.php:147
msgid "There was a problem accessing the weather data. But have a look"
msgstr ""
#: curweather.php:149
msgid "at OpenWeatherMap"
msgstr ""
#: curweather.php:178
msgid "No APPID found, please contact your admin to obtain one."
msgstr ""
#: curweather.php:188
msgid "Enter either the name of your location or the zip code."
msgstr ""
#: curweather.php:189
msgid "Your Location"
msgstr ""
#: curweather.php:189
msgid ""
"Identifier of your location (name or zip code), e.g. <em>Berlin,DE</em> or "
"<em>14476,DE</em>."
msgstr ""
#: curweather.php:190
msgid "Units"
msgstr ""
#: curweather.php:190
msgid "select if the temperature should be displayed in &deg;C or &deg;F"
msgstr ""
#: curweather.php:191
msgid "Show weather data"
msgstr ""
#: curweather.php:196
msgid "Current Weather Settings"
msgstr ""
#: curweather.php:227
msgid "Save Settings"
msgstr ""
#: curweather.php:230
msgid "Caching Interval"
msgstr ""
#: curweather.php:232
msgid ""
"For how long should the weather data be cached? Choose according your "
"OpenWeatherMap account type."
msgstr ""
#: curweather.php:233
msgid "no cache"
msgstr ""
#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237
msgid "minutes"
msgstr ""
#: curweather.php:240
msgid "Your APPID"
msgstr ""
#: curweather.php:240
msgid "Your API key provided by OpenWeatherMap"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,123 @@
# ADDON curweather
# Copyright (C)
# This file is distributed under the same license as the Friendica curweather addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 11:34+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: curweather.php:47
msgid "Error fetching weather data. Error was: "
msgstr ""
#: curweather.php:130
msgid "Current Weather"
msgstr ""
#: curweather.php:137
msgid "Relative Humidity"
msgstr ""
#: curweather.php:138
msgid "Pressure"
msgstr ""
#: curweather.php:139
msgid "Wind"
msgstr ""
#: curweather.php:140
msgid "Last Updated"
msgstr ""
#: curweather.php:141
msgid "Data by"
msgstr ""
#: curweather.php:142
msgid "Show on map"
msgstr ""
#: curweather.php:147
msgid "There was a problem accessing the weather data. But have a look"
msgstr ""
#: curweather.php:149
msgid "at OpenWeatherMap"
msgstr ""
#: curweather.php:178
msgid "No APPID found, please contact your admin to obtain one."
msgstr ""
#: curweather.php:188
msgid "Enter either the name of your location or the zip code."
msgstr ""
#: curweather.php:189
msgid "Your Location"
msgstr ""
#: curweather.php:189
msgid ""
"Identifier of your location (name or zip code), e.g. <em>Berlin,DE</em> or "
"<em>14476,DE</em>."
msgstr ""
#: curweather.php:190
msgid "Units"
msgstr ""
#: curweather.php:190
msgid "select if the temperature should be displayed in &deg;C or &deg;F"
msgstr ""
#: curweather.php:191
msgid "Show weather data"
msgstr ""
#: curweather.php:196
msgid "Current Weather Settings"
msgstr ""
#: curweather.php:227
msgid "Save Settings"
msgstr ""
#: curweather.php:230
msgid "Caching Interval"
msgstr ""
#: curweather.php:232
msgid ""
"For how long should the weather data be cached? Choose according your "
"OpenWeatherMap account type."
msgstr ""
#: curweather.php:233
msgid "no cache"
msgstr ""
#: curweather.php:234 curweather.php:235 curweather.php:236 curweather.php:237
msgid "minutes"
msgstr ""
#: curweather.php:240
msgid "Your APPID"
msgstr ""
#: curweather.php:240
msgid "Your API key provided by OpenWeatherMap"
msgstr ""

View file

@ -1,3 +1,7 @@
<?php
$a->strings["Submit"] = "Senda inn";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -33,7 +33,6 @@ class Diaspora_Connection {
}
$this->cookiejar = tempnam(System::getTempPath(), 'cookies');
return $this;
}
public function __destruct() {

View file

@ -9,6 +9,8 @@ use Friendica\Core\System;
class Diasphp {
private $cookiejar;
private $token_regex;
private $pod;
function __construct($pod) {
$this->token_regex = '/content="(.*?)" name="csrf-token/';

View file

@ -9,10 +9,8 @@
require_once 'addon/diaspora/Diaspora_Connection.php';
use Friendica\App;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\Core\Worker;
@ -187,7 +185,7 @@ function diaspora_send(array &$b)
{
$hostname = DI::baseUrl()->getHost();
Logger::notice('diaspora_send: invoked');
DI::logger()->notice('diaspora_send: invoked');
if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) {
return;
@ -197,6 +195,10 @@ function diaspora_send(array &$b)
return;
}
if (Item::isGroupPost($b['uri-id'])) {
return;
}
if ($b['parent'] != $b['id']) {
return;
}
@ -211,14 +213,14 @@ function diaspora_send(array &$b)
return;
}
Logger::info('diaspora_send: prepare posting');
DI::logger()->info('diaspora_send: prepare posting');
$handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle');
$password = DI::pConfig()->get($b['uid'], 'diaspora', 'password');
$aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect');
if ($handle && $password) {
Logger::info('diaspora_send: all values seem to be okay');
DI::logger()->info('diaspora_send: all values seem to be okay');
$title = $b['title'];
$body = $b['body'];
@ -249,20 +251,20 @@ function diaspora_send(array &$b)
require_once "addon/diaspora/diasphp.php";
try {
Logger::info('diaspora_send: prepare');
DI::logger()->info('diaspora_send: prepare');
$conn = new Diaspora_Connection($handle, $password);
Logger::info('diaspora_send: try to log in ' . $handle);
DI::logger()->info('diaspora_send: try to log in ' . $handle);
$conn->logIn();
Logger::info('diaspora_send: try to send ' . $body);
DI::logger()->info('diaspora_send: try to send ' . $body);
$conn->provider = $hostname;
$conn->postStatusMessage($body, $aspect);
Logger::notice('diaspora_send: success');
DI::logger()->notice('diaspora_send: success');
} catch (Exception $e) {
Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage());
DI::logger()->notice("diaspora_send: Error submitting the post: " . $e->getMessage());
Logger::info('diaspora_send: requeueing ' . $b['uid']);
DI::logger()->info('diaspora_send: requeueing ' . $b['uid']);
Worker::defer();
}

View file

@ -0,0 +1,101 @@
# ADDON diaspora
# Copyright (C)
# This file is distributed under the same license as the Friendica diaspora addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-03 15:48-0400\n"
"PO-Revision-Date: 2014-06-22 11:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: diaspora.php:43
msgid "Post to Diaspora"
msgstr ""
#: diaspora.php:66
#, php-format
msgid ""
"Please remember: You can always be reached from Diaspora with your Friendica"
" handle <strong>%s</strong>. "
msgstr ""
#: diaspora.php:67
msgid ""
"This connector is only meant if you still want to use your old Diaspora "
"account for some time. "
msgstr ""
#: diaspora.php:68
#, php-format
msgid ""
"However, it is preferred that you tell your Diaspora contacts the new handle"
" <strong>%s</strong> instead."
msgstr ""
#: diaspora.php:78
msgid "All aspects"
msgstr ""
#: diaspora.php:79
msgid "Public"
msgstr ""
#: diaspora.php:85
msgid "Post to aspect:"
msgstr ""
#: diaspora.php:86
#, php-format
msgid "Connected with your Diaspora account <strong>%s</strong>"
msgstr ""
#: diaspora.php:89
msgid ""
"Can't login to your Diaspora account. Please check handle (in the format "
"user@domain.tld) and password."
msgstr ""
#: diaspora.php:96
msgid "Information"
msgstr ""
#: diaspora.php:97
msgid "Error"
msgstr ""
#: diaspora.php:103
msgid "Enable Diaspora Post Addon"
msgstr ""
#: diaspora.php:104
msgid "Diaspora handle"
msgstr ""
#: diaspora.php:105
msgid "Diaspora password"
msgstr ""
#: diaspora.php:105
msgid ""
"Privacy notice: Your Diaspora password will be stored unencrypted to "
"authenticate you with your Diaspora pod. This means your Friendica node "
"administrator can have access to it."
msgstr ""
#: diaspora.php:107
msgid "Post to Diaspora by default"
msgstr ""
#: diaspora.php:112
msgid "Diaspora Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,101 @@
# ADDON diaspora
# Copyright (C)
# This file is distributed under the same license as the Friendica diaspora addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-03 15:48-0400\n"
"PO-Revision-Date: 2014-06-22 11:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: diaspora.php:43
msgid "Post to Diaspora"
msgstr ""
#: diaspora.php:66
#, php-format
msgid ""
"Please remember: You can always be reached from Diaspora with your Friendica"
" handle <strong>%s</strong>. "
msgstr ""
#: diaspora.php:67
msgid ""
"This connector is only meant if you still want to use your old Diaspora "
"account for some time. "
msgstr ""
#: diaspora.php:68
#, php-format
msgid ""
"However, it is preferred that you tell your Diaspora contacts the new handle"
" <strong>%s</strong> instead."
msgstr ""
#: diaspora.php:78
msgid "All aspects"
msgstr ""
#: diaspora.php:79
msgid "Public"
msgstr ""
#: diaspora.php:85
msgid "Post to aspect:"
msgstr ""
#: diaspora.php:86
#, php-format
msgid "Connected with your Diaspora account <strong>%s</strong>"
msgstr ""
#: diaspora.php:89
msgid ""
"Can't login to your Diaspora account. Please check handle (in the format "
"user@domain.tld) and password."
msgstr ""
#: diaspora.php:96
msgid "Information"
msgstr ""
#: diaspora.php:97
msgid "Error"
msgstr ""
#: diaspora.php:103
msgid "Enable Diaspora Post Addon"
msgstr ""
#: diaspora.php:104
msgid "Diaspora handle"
msgstr ""
#: diaspora.php:105
msgid "Diaspora password"
msgstr ""
#: diaspora.php:105
msgid ""
"Privacy notice: Your Diaspora password will be stored unencrypted to "
"authenticate you with your Diaspora pod. This means your Friendica node "
"administrator can have access to it."
msgstr ""
#: diaspora.php:107
msgid "Post to Diaspora by default"
msgstr ""
#: diaspora.php:112
msgid "Diaspora Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,101 @@
# ADDON diaspora
# Copyright (C)
# This file is distributed under the same license as the Friendica diaspora addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-03 15:48-0400\n"
"PO-Revision-Date: 2014-06-22 11:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: diaspora.php:43
msgid "Post to Diaspora"
msgstr ""
#: diaspora.php:66
#, php-format
msgid ""
"Please remember: You can always be reached from Diaspora with your Friendica"
" handle <strong>%s</strong>. "
msgstr ""
#: diaspora.php:67
msgid ""
"This connector is only meant if you still want to use your old Diaspora "
"account for some time. "
msgstr ""
#: diaspora.php:68
#, php-format
msgid ""
"However, it is preferred that you tell your Diaspora contacts the new handle"
" <strong>%s</strong> instead."
msgstr ""
#: diaspora.php:78
msgid "All aspects"
msgstr ""
#: diaspora.php:79
msgid "Public"
msgstr ""
#: diaspora.php:85
msgid "Post to aspect:"
msgstr ""
#: diaspora.php:86
#, php-format
msgid "Connected with your Diaspora account <strong>%s</strong>"
msgstr ""
#: diaspora.php:89
msgid ""
"Can't login to your Diaspora account. Please check handle (in the format "
"user@domain.tld) and password."
msgstr ""
#: diaspora.php:96
msgid "Information"
msgstr ""
#: diaspora.php:97
msgid "Error"
msgstr ""
#: diaspora.php:103
msgid "Enable Diaspora Post Addon"
msgstr ""
#: diaspora.php:104
msgid "Diaspora handle"
msgstr ""
#: diaspora.php:105
msgid "Diaspora password"
msgstr ""
#: diaspora.php:105
msgid ""
"Privacy notice: Your Diaspora password will be stored unencrypted to "
"authenticate you with your Diaspora pod. This means your Friendica node "
"administrator can have access to it."
msgstr ""
#: diaspora.php:107
msgid "Post to Diaspora by default"
msgstr ""
#: diaspora.php:112
msgid "Diaspora Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,101 @@
# ADDON diaspora
# Copyright (C)
# This file is distributed under the same license as the Friendica diaspora addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-03 15:48-0400\n"
"PO-Revision-Date: 2014-06-22 11:39+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: diaspora.php:43
msgid "Post to Diaspora"
msgstr ""
#: diaspora.php:66
#, php-format
msgid ""
"Please remember: You can always be reached from Diaspora with your Friendica"
" handle <strong>%s</strong>. "
msgstr ""
#: diaspora.php:67
msgid ""
"This connector is only meant if you still want to use your old Diaspora "
"account for some time. "
msgstr ""
#: diaspora.php:68
#, php-format
msgid ""
"However, it is preferred that you tell your Diaspora contacts the new handle"
" <strong>%s</strong> instead."
msgstr ""
#: diaspora.php:78
msgid "All aspects"
msgstr ""
#: diaspora.php:79
msgid "Public"
msgstr ""
#: diaspora.php:85
msgid "Post to aspect:"
msgstr ""
#: diaspora.php:86
#, php-format
msgid "Connected with your Diaspora account <strong>%s</strong>"
msgstr ""
#: diaspora.php:89
msgid ""
"Can't login to your Diaspora account. Please check handle (in the format "
"user@domain.tld) and password."
msgstr ""
#: diaspora.php:96
msgid "Information"
msgstr ""
#: diaspora.php:97
msgid "Error"
msgstr ""
#: diaspora.php:103
msgid "Enable Diaspora Post Addon"
msgstr ""
#: diaspora.php:104
msgid "Diaspora handle"
msgstr ""
#: diaspora.php:105
msgid "Diaspora password"
msgstr ""
#: diaspora.php:105
msgid ""
"Privacy notice: Your Diaspora password will be stored unencrypted to "
"authenticate you with your Diaspora pod. This means your Friendica node "
"administrator can have access to it."
msgstr ""
#: diaspora.php:107
msgid "Post to Diaspora by default"
msgstr ""
#: diaspora.php:112
msgid "Diaspora Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -4,100 +4,101 @@
#
#
# Translators:
# Piotr Strębski <strebski@gmail.com>, 2022
# Bartosz Kozień, 2025
# Piotr Strebski <strebski@gmail.com>, 2022
# Waldemar Stoczkowski, 2018,2020
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"POT-Creation-Date: 2023-06-03 15:48-0400\n"
"PO-Revision-Date: 2014-06-22 11:39+0000\n"
"Last-Translator: Piotr Strębski <strebski@gmail.com>, 2022\n"
"Language-Team: Polish (http://www.transifex.com/Friendica/friendica/language/pl/)\n"
"Last-Translator: Bartosz Kozień, 2025\n"
"Language-Team: Polish (http://app.transifex.com/Friendica/friendica/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
#: diaspora.php:44
#: diaspora.php:43
msgid "Post to Diaspora"
msgstr "Napisz do Diaspory"
#: diaspora.php:67
#: diaspora.php:66
#, php-format
msgid ""
"Please remember: You can always be reached from Diaspora with your Friendica"
" handle <strong>%s</strong>. "
msgstr "Pamiętaj: Zawsze można do Ciebie dotrzeć z Diaspory za pomocą uchwytu Friendica <strong>%s</strong>. "
#: diaspora.php:68
#: diaspora.php:67
msgid ""
"This connector is only meant if you still want to use your old Diaspora "
"account for some time. "
msgstr "Ten łącznik jest przeznaczony do tego, gdy nadal chcesz korzystać ze starego konta Diaspora przez jakiś czas."
#: diaspora.php:69
#: diaspora.php:68
#, php-format
msgid ""
"However, it is preferred that you tell your Diaspora contacts the new handle"
" <strong>%s</strong> instead."
msgstr "Jednak zaleca się, aby zamiast tego poinformować swoją Diasporę o kontakt z nowym uchwytem <strong>%s</strong>."
#: diaspora.php:79
#: diaspora.php:78
msgid "All aspects"
msgstr "Wszystkie aspekty"
#: diaspora.php:80
#: diaspora.php:79
msgid "Public"
msgstr "Publiczny"
#: diaspora.php:86
#: diaspora.php:85
msgid "Post to aspect:"
msgstr "Napisz do aspektu:"
#: diaspora.php:87
#: diaspora.php:86
#, php-format
msgid "Connected with your Diaspora account <strong>%s</strong>"
msgstr "Połączony ze swoim kontem Diaspora <strong>%s</strong>"
#: diaspora.php:90
#: diaspora.php:89
msgid ""
"Can't login to your Diaspora account. Please check handle (in the format "
"user@domain.tld) and password."
msgstr "Nie można zalogować się na Twoje konto w Diasporze. Sprawdź uchwyt (w formacie użytkownik@domena.tld) i hasło."
#: diaspora.php:97
#: diaspora.php:96
msgid "Information"
msgstr "Informacja"
#: diaspora.php:98
#: diaspora.php:97
msgid "Error"
msgstr "Błąd"
#: diaspora.php:104
#: diaspora.php:103
msgid "Enable Diaspora Post Addon"
msgstr "Włącz dodatek Diaspora"
#: diaspora.php:105
#: diaspora.php:104
msgid "Diaspora handle"
msgstr "Uchwyt Diaspory"
#: diaspora.php:106
#: diaspora.php:105
msgid "Diaspora password"
msgstr "Hasło Diaspora"
#: diaspora.php:106
#: diaspora.php:105
msgid ""
"Privacy notice: Your Diaspora password will be stored unencrypted to "
"authenticate you with your Diaspora pod. This means your Friendica node "
"administrator can have access to it."
msgstr "Informacja o ochronie prywatności: Twoje hasło Diaspora będzie przechowywane w postaci niezaszyfrowanej w celu uwierzytelnienia użytkownika za pomocą Diaspora. Oznacza to, że administrator węzła Friendica może mieć do niego dostęp."
msgstr "Informacja o prywatności: Twoje hasło Diaspora będzie przechowywane w postaci niezaszyfrowanej w celu uwierzytelnienia użytkownika w instancji Diaspora. Oznacza to, że administrator instancji Friendica może mieć do niego dostęp."
#: diaspora.php:108
#: diaspora.php:107
msgid "Post to Diaspora by default"
msgstr "Wyślij domyślnie do Diaspory"
#: diaspora.php:113
#: diaspora.php:112
msgid "Diaspora Export"
msgstr "Eksportuj do Diaspory"

View file

@ -19,6 +19,6 @@ $a->strings['Error'] = 'Błąd';
$a->strings['Enable Diaspora Post Addon'] = 'Włącz dodatek Diaspora';
$a->strings['Diaspora handle'] = 'Uchwyt Diaspory';
$a->strings['Diaspora password'] = 'Hasło Diaspora';
$a->strings['Privacy notice: Your Diaspora password will be stored unencrypted to authenticate you with your Diaspora pod. This means your Friendica node administrator can have access to it.'] = 'Informacja o ochronie prywatności: Twoje hasło Diaspora będzie przechowywane w postaci niezaszyfrowanej w celu uwierzytelnienia użytkownika za pomocą Diaspora. Oznacza to, że administrator węzła Friendica może mieć do niego dostęp.';
$a->strings['Privacy notice: Your Diaspora password will be stored unencrypted to authenticate you with your Diaspora pod. This means your Friendica node administrator can have access to it.'] = 'Informacja o prywatności: Twoje hasło Diaspora będzie przechowywane w postaci niezaszyfrowanej w celu uwierzytelnienia użytkownika w instancji Diaspora. Oznacza to, że administrator instancji Friendica może mieć do niego dostęp.';
$a->strings['Post to Diaspora by default'] = 'Wyślij domyślnie do Diaspory';
$a->strings['Diaspora Export'] = 'Eksportuj do Diaspory';

View file

@ -8,10 +8,8 @@
*
*/
use Friendica\App;
use Friendica\Content\Text\Markdown;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
@ -80,13 +78,13 @@ function discourse_email_getmessage(&$message)
// We do assume that all Discourse servers are running with SSL
if (preg_match('=topic/(.*\d)/(.*\d)@(.*)=', $message['item']['uri'], $matches) &&
discourse_fetch_post_from_api($message, $matches[2], $matches[3])) {
Logger::info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]);
DI::logger()->info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]);
return;
}
if (preg_match('=topic/(.*\d)@(.*)=', $message['item']['uri'], $matches) &&
discourse_fetch_topic_from_api($message, 'https://' . $matches[2], $matches[1], 1)) {
Logger::info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]);
DI::logger()->info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]);
return;
}
@ -96,16 +94,16 @@ function discourse_email_getmessage(&$message)
}
if (empty($message['item']['plink']) || !preg_match('=(http.*)/t/.*/(.*\d)/(.*\d)=', $message['item']['plink'], $matches)) {
Logger::info('This is no Discourse post');
DI::logger()->info('This is no Discourse post');
return;
}
if (discourse_fetch_topic_from_api($message, $matches[1], $matches[2], $matches[3])) {
Logger::info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]);
DI::logger()->info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]);
return;
}
Logger::info('Fallback mode', ['plink' => $message['item']['plink']]);
DI::logger()->info('Fallback mode', ['plink' => $message['item']['plink']]);
// Search in the HTML part for the discourse entry and the author profile
if (!empty($message['html'])) {
$message = discourse_get_html($message);
@ -122,7 +120,7 @@ function discourse_fetch_post($host, $topic, $pid)
$url = $host . '/t/' . $topic . '/' . $pid . '.json';
$curlResult = DI::httpClient()->get($url);
if (!$curlResult->isSuccess()) {
Logger::info('No success', ['url' => $url]);
DI::logger()->info('No success', ['url' => $url]);
return false;
}
@ -134,11 +132,11 @@ function discourse_fetch_post($host, $topic, $pid)
/// @todo Possibly fetch missing posts here
continue;
}
Logger::info('Got post data from topic', $post);
DI::logger()->info('Got post data from topic', $post);
return $post;
}
Logger::info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]);
DI::logger()->info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]);
return false;
}
@ -170,7 +168,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host)
$message = discourse_process_post($message, $data, $hostaddr);
Logger::info('Got API data', $message);
DI::logger()->info('Got API data', $message);
return true;
}
@ -203,7 +201,7 @@ function discourse_get_user($post, $hostaddr)
$contact['url'] = $hostaddr . '/u/' . $contact['nick'];
$contact['nurl'] = Strings::normaliseLink($contact['url']);
$contact['baseurl'] = $hostaddr;
Logger::info('Contact', $contact);
DI::logger()->info('Contact', $contact);
$contact['id'] = Contact::getIdForURL($contact['url'], 0, false, $contact);
if (!empty($contact['id'])) {
$avatar = $contact['photo'];
@ -269,11 +267,11 @@ function discourse_get_html($message)
$div = $doc2->importNode($result->item(0), true);
$doc2->appendChild($div);
$message['html'] = $doc2->saveHTML();
Logger::info('Found html body', ['html' => $message['html']]);
DI::logger()->info('Found html body', ['html' => $message['html']]);
$profile = discourse_get_profile($xpath);
if (!empty($profile['url'])) {
Logger::info('Found profile', $profile);
DI::logger()->info('Found profile', $profile);
$message['item']['author-id'] = Contact::getIdForURL($profile['url'], 0, false, $profile);
$message['item']['author-link'] = $profile['url'];
$message['item']['author-name'] = $profile['name'];
@ -289,21 +287,21 @@ function discourse_get_text($message)
$text = str_replace("\r", '', $text);
$pos = strpos($text, "\n---\n");
if ($pos == 0) {
Logger::info('No separator found', ['text' => $text]);
DI::logger()->info('No separator found', ['text' => $text]);
return $message;
}
$message['text'] = trim(substr($text, 0, $pos));
Logger::info('Found text body', ['text' => $message['text']]);
DI::logger()->info('Found text body', ['text' => $message['text']]);
$message['text'] = Markdown::toBBCode($message['text']);
$text = substr($text, $pos);
Logger::info('Found footer', ['text' => $text]);
DI::logger()->info('Found footer', ['text' => $text]);
if (preg_match('=\((http.*/t/.*/.*\d/.*\d)\)=', $text, $link)) {
$message['item']['plink'] = $link[1];
Logger::info('Found plink', ['plink' => $message['item']['plink']]);
DI::logger()->info('Found plink', ['plink' => $message['item']['plink']]);
}
return $message;
}

View file

@ -8,10 +8,8 @@
* Author: Cat Gray <https://free-haven.org/profile/catness>
*/
use Friendica\App;
use Friendica\Content\Text\BBCode;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Item;
@ -127,6 +125,10 @@ function dwpost_send(array &$b)
return;
}
if (Item::isGroupPost($b['uri-id'])) {
return;
}
if ($b['parent'] != $b['id']) {
return;
}
@ -186,12 +188,12 @@ function dwpost_send(array &$b)
EOT;
Logger::debug('dwpost: data: ' . $xml);
DI::logger()->debug('dwpost: data: ' . $xml);
if ($dw_blog !== 'test') {
$x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString();
}
Logger::info('posted to dreamwidth: ' . ($x) ? $x : '');
DI::logger()->info('posted to dreamwidth: ' . ($x) ? $x : '');
}
}

View file

@ -0,0 +1,43 @@
# ADDON dwpost
# Copyright (C)
# This file is distributed under the same license as the Friendica dwpost addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2014-06-22 11:41+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: dwpost.php:43
msgid "Post to Dreamwidth"
msgstr ""
#: dwpost.php:63
msgid "Enable Dreamwidth Post Addon"
msgstr ""
#: dwpost.php:64
msgid "Dreamwidth username"
msgstr ""
#: dwpost.php:65
msgid "Dreamwidth password"
msgstr ""
#: dwpost.php:66
msgid "Post to Dreamwidth by default"
msgstr ""
#: dwpost.php:71
msgid "Dreamwidth Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,43 @@
# ADDON dwpost
# Copyright (C)
# This file is distributed under the same license as the Friendica dwpost addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2014-06-22 11:41+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: dwpost.php:43
msgid "Post to Dreamwidth"
msgstr ""
#: dwpost.php:63
msgid "Enable Dreamwidth Post Addon"
msgstr ""
#: dwpost.php:64
msgid "Dreamwidth username"
msgstr ""
#: dwpost.php:65
msgid "Dreamwidth password"
msgstr ""
#: dwpost.php:66
msgid "Post to Dreamwidth by default"
msgstr ""
#: dwpost.php:71
msgid "Dreamwidth Export"
msgstr ""

View file

@ -1,9 +1,7 @@
<?php
$a->strings["Post to Dreamwidth"] = "Afiŝi al Dreamwidth";
$a->strings["Dreamwidth Post Settings"] = "Agordoj por Afiŝoj al Dreamwidth";
$a->strings["Enable dreamwidth Post Addon"] = "Ŝalti la Dreamwidth Kromprogramon";
$a->strings["dreamwidth username"] = "Dreamwidth salutnomo";
$a->strings["dreamwidth password"] = "Dreamwidth pasvorto";
$a->strings["Post to dreamwidth by default"] = "Defaŭlte afiŝi al Dreamwidth";
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,44 @@
# ADDON dwpost
# Copyright (C)
# This file is distributed under the same license as the Friendica dwpost addon package.
#
#
# Translators:
# Rain Hawk, 2020
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2014-06-22 11:41+0000\n"
"Last-Translator: Rain Hawk, 2020\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: dwpost.php:43
msgid "Post to Dreamwidth"
msgstr ""
#: dwpost.php:63
msgid "Enable Dreamwidth Post Addon"
msgstr ""
#: dwpost.php:64
msgid "Dreamwidth username"
msgstr ""
#: dwpost.php:65
msgid "Dreamwidth password"
msgstr ""
#: dwpost.php:66
msgid "Post to Dreamwidth by default"
msgstr ""
#: dwpost.php:71
msgid "Dreamwidth Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,43 @@
# ADDON dwpost
# Copyright (C)
# This file is distributed under the same license as the Friendica dwpost addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2014-06-22 11:41+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: dwpost.php:43
msgid "Post to Dreamwidth"
msgstr ""
#: dwpost.php:63
msgid "Enable Dreamwidth Post Addon"
msgstr ""
#: dwpost.php:64
msgid "Dreamwidth username"
msgstr ""
#: dwpost.php:65
msgid "Dreamwidth password"
msgstr ""
#: dwpost.php:66
msgid "Post to Dreamwidth by default"
msgstr ""
#: dwpost.php:71
msgid "Dreamwidth Export"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,43 @@
# ADDON dwpost
# Copyright (C)
# This file is distributed under the same license as the Friendica dwpost addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2014-06-22 11:41+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: dwpost.php:43
msgid "Post to Dreamwidth"
msgstr ""
#: dwpost.php:63
msgid "Enable Dreamwidth Post Addon"
msgstr ""
#: dwpost.php:64
msgid "Dreamwidth username"
msgstr ""
#: dwpost.php:65
msgid "Dreamwidth password"
msgstr ""
#: dwpost.php:66
msgid "Post to Dreamwidth by default"
msgstr ""
#: dwpost.php:71
msgid "Dreamwidth Export"
msgstr ""

View file

@ -1,9 +1,7 @@
<?php
$a->strings["Post to Dreamwidth"] = "";
$a->strings["Dreamwidth Post Settings"] = "";
$a->strings["Enable dreamwidth Post Addon"] = "";
$a->strings["dreamwidth username"] = "";
$a->strings["dreamwidth password"] = "";
$a->strings["Post to dreamwidth by default"] = "";
$a->strings["Submit"] = "Senda inn";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

2
fancybox/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/dist/
/test/

27
fancybox/CHANGELOG.md Normal file
View file

@ -0,0 +1,27 @@
### Version 1.05
* Added ALT and TITLE of original IMG to fancybox popup.
### Version 1.04
* Update supporting upcoming imnagegrid in posts
### Version 1.03
* imgages in body-attach with title / alt attribute get them removed while adding fancy attributes
* Added fancybox to image inlined in posts. Un-hooked the old lightbox from frio and vier and excahnged that with fancybox hooks.
* Excluded images in "type-link" divs from being "fancied" as they have no images but pages linked to.
### Version 1.02
* [MrPetovan](https://github.com/MrPetovan) optimized my noob regular expression code.
### Version 1.01
* One gallery for each post
* All media attached to a post are added to the posts gallery.
* Loop scrolling: You can step from last media to first and vice versa.
### Version 1.00
* First test version released.
* One fancybox per page displaying first media of each post.

19
fancybox/README.md Normal file
View file

@ -0,0 +1,19 @@
# Post image gallery using fancybox
Addon author: [Grischa Brockhaus](https://brockha.us)
## Description
This addon loads all media attachments of a post into a "fancybox" instead of linking directly to the media.
Each post gets its own attachment library, when there are more than one media attached you can scroll through them.
## Licenses
### Fancybox Library
This AddOn is using the jQuery library [fancybox](https://github.com/fancyapps/fancybox).
The fancyBox libryry is licensed under the GPLv3 license for all open source applications. A commercial license is required for all commercial applications (including sites, themes and apps you plan to sell).
[Read more about fancyBox license](https://github.com/fancyapps/fancybox).

View file

@ -0,0 +1,62 @@
# fancyBox 3.5.7
jQuery lightbox script for displaying images, videos and more.
Touch enabled, responsive and fully customizable.
See the [project page](http://fancyapps.com/fancybox/3/) for documentation and a demonstration.
Follow [@thefancyapps](//twitter.com/thefancyapps) for updates.
## Quick start
1\. Add latest jQuery and fancyBox files
```html
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<link href="/path/to/jquery.fancybox.min.css" rel="stylesheet">
<script src="/path/to/jquery.fancybox.min.js"></script>
```
2\. Create links
```html
<a data-fancybox="gallery" href="big_1.jpg">
<img src="small_1.jpg">
</a>
<a data-fancybox="gallery" href="big_2.jpg">
<img src="small_2.jpg">
</a>
```
3\. Enjoy!
## License
fancyBox is licensed under the [GPLv3](http://choosealicense.com/licenses/gpl-3.0) license for all open source applications.
A commercial license is required for all commercial applications (including sites, themes and apps you plan to sell).
[Read more about fancyBox license](http://fancyapps.com/fancybox/3/#license).
## Bugs and feature requests
If you find a bug, please report it [here on Github](https://github.com/fancyapps/fancybox/issues).
Guidelines for bug reports:
1. Use the GitHub issue search — check if the issue has already been reported.
2. Check if the issue has been fixed — try to reproduce it using the latest master or development branch in the repository.
3. Isolate the problem — create a reduced test case and a live example. You can use CodePen to fork any demo found on documentation to use it as a template.
A good bug report shouldn't leave others needing to chase you up for more information.
Please try to be as detailed as possible in your report.
Feature requests are welcome. Please look for existing ones and use GitHub's "reactions" feature to vote.
Please do not use the issue tracker for personal support requests - use Stack Overflow ([fancybox-3](http://stackoverflow.com/questions/tagged/fancybox-3) tag) instead.

View file

@ -0,0 +1,13 @@
$(document).ready(function() {
$.fancybox.defaults.loop = "true";
// this disables the colorbox hook found in frio/js/modal.js:34
$("body").off("click", ".wall-item-body a img");
// Adds ALT/TITLE text to fancybox
$('a[data-fancybox').fancybox({
afterLoad : function(instance, current) {
current.$image.attr('alt', current.opts.$orig.find('img').attr('alt') );
current.$image.attr('title', current.opts.$orig.find('img').attr('title') );
}
});
});

View file

@ -0,0 +1,895 @@
body.compensate-for-scrollbar {
overflow: hidden;
}
.fancybox-active {
height: auto;
}
.fancybox-is-hidden {
left: -9999px;
margin: 0;
position: absolute !important;
top: -9999px;
visibility: hidden;
}
.fancybox-container {
-webkit-backface-visibility: hidden;
height: 100%;
left: 0;
outline: none;
position: fixed;
-webkit-tap-highlight-color: transparent;
top: 0;
-ms-touch-action: manipulation;
touch-action: manipulation;
transform: translateZ(0);
width: 100%;
z-index: 99992;
}
.fancybox-container * {
box-sizing: border-box;
}
.fancybox-outer,
.fancybox-inner,
.fancybox-bg,
.fancybox-stage {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.fancybox-outer {
-webkit-overflow-scrolling: touch;
overflow-y: auto;
}
.fancybox-bg {
background: rgb(30, 30, 30);
opacity: 0;
transition-duration: inherit;
transition-property: opacity;
transition-timing-function: cubic-bezier(.47, 0, .74, .71);
}
.fancybox-is-open .fancybox-bg {
opacity: .9;
transition-timing-function: cubic-bezier(.22, .61, .36, 1);
}
.fancybox-infobar,
.fancybox-toolbar,
.fancybox-caption,
.fancybox-navigation .fancybox-button {
direction: ltr;
opacity: 0;
position: absolute;
transition: opacity .25s ease, visibility 0s ease .25s;
visibility: hidden;
z-index: 99997;
}
.fancybox-show-infobar .fancybox-infobar,
.fancybox-show-toolbar .fancybox-toolbar,
.fancybox-show-caption .fancybox-caption,
.fancybox-show-nav .fancybox-navigation .fancybox-button {
opacity: 1;
transition: opacity .25s ease 0s, visibility 0s ease 0s;
visibility: visible;
}
.fancybox-infobar {
color: #ccc;
font-size: 13px;
-webkit-font-smoothing: subpixel-antialiased;
height: 44px;
left: 0;
line-height: 44px;
min-width: 44px;
mix-blend-mode: difference;
padding: 0 10px;
pointer-events: none;
top: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.fancybox-toolbar {
right: 0;
top: 0;
}
.fancybox-stage {
direction: ltr;
overflow: visible;
transform: translateZ(0);
z-index: 99994;
}
.fancybox-is-open .fancybox-stage {
overflow: hidden;
}
.fancybox-slide {
-webkit-backface-visibility: hidden;
/* Using without prefix would break IE11 */
display: none;
height: 100%;
left: 0;
outline: none;
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 44px;
position: absolute;
text-align: center;
top: 0;
transition-property: transform, opacity;
white-space: normal;
width: 100%;
z-index: 99994;
}
.fancybox-slide::before {
content: '';
display: inline-block;
font-size: 0;
height: 100%;
vertical-align: middle;
width: 0;
}
.fancybox-is-sliding .fancybox-slide,
.fancybox-slide--previous,
.fancybox-slide--current,
.fancybox-slide--next {
display: block;
}
.fancybox-slide--image {
overflow: hidden;
padding: 44px 0;
}
.fancybox-slide--image::before {
display: none;
}
.fancybox-slide--html {
padding: 6px;
}
.fancybox-content {
background: #fff;
display: inline-block;
margin: 0;
max-width: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 44px;
position: relative;
text-align: left;
vertical-align: middle;
}
.fancybox-slide--image .fancybox-content {
animation-timing-function: cubic-bezier(.5, 0, .14, 1);
-webkit-backface-visibility: hidden;
background: transparent;
background-repeat: no-repeat;
background-size: 100% 100%;
left: 0;
max-width: none;
overflow: visible;
padding: 0;
position: absolute;
top: 0;
-ms-transform-origin: top left;
transform-origin: top left;
transition-property: transform, opacity;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 99995;
}
.fancybox-can-zoomOut .fancybox-content {
cursor: zoom-out;
}
.fancybox-can-zoomIn .fancybox-content {
cursor: zoom-in;
}
.fancybox-can-swipe .fancybox-content,
.fancybox-can-pan .fancybox-content {
cursor: -webkit-grab;
cursor: grab;
}
.fancybox-is-grabbing .fancybox-content {
cursor: -webkit-grabbing;
cursor: grabbing;
}
.fancybox-container [data-selectable='true'] {
cursor: text;
}
.fancybox-image,
.fancybox-spaceball {
background: transparent;
border: 0;
height: 100%;
left: 0;
margin: 0;
max-height: none;
max-width: none;
padding: 0;
position: absolute;
top: 0;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
width: 100%;
}
.fancybox-spaceball {
z-index: 1;
}
.fancybox-slide--video .fancybox-content,
.fancybox-slide--map .fancybox-content,
.fancybox-slide--pdf .fancybox-content,
.fancybox-slide--iframe .fancybox-content {
height: 100%;
overflow: visible;
padding: 0;
width: 100%;
}
.fancybox-slide--video .fancybox-content {
background: #000;
}
.fancybox-slide--map .fancybox-content {
background: #e5e3df;
}
.fancybox-slide--iframe .fancybox-content {
background: #fff;
}
.fancybox-video,
.fancybox-iframe {
background: transparent;
border: 0;
display: block;
height: 100%;
margin: 0;
overflow: hidden;
padding: 0;
width: 100%;
}
/* Fix iOS */
.fancybox-iframe {
left: 0;
position: absolute;
top: 0;
}
.fancybox-error {
background: #fff;
cursor: default;
max-width: 400px;
padding: 40px;
width: 100%;
}
.fancybox-error p {
color: #444;
font-size: 16px;
line-height: 20px;
margin: 0;
padding: 0;
}
/* Buttons */
.fancybox-button {
background: rgba(30, 30, 30, .6);
border: 0;
border-radius: 0;
box-shadow: none;
cursor: pointer;
display: inline-block;
height: 44px;
margin: 0;
padding: 10px;
position: relative;
transition: color .2s;
vertical-align: top;
visibility: inherit;
width: 44px;
}
.fancybox-button,
.fancybox-button:visited,
.fancybox-button:link {
color: #ccc;
}
.fancybox-button:hover {
color: #fff;
}
.fancybox-button:focus {
outline: none;
}
.fancybox-button.fancybox-focus {
outline: 1px dotted;
}
.fancybox-button[disabled],
.fancybox-button[disabled]:hover {
color: #888;
cursor: default;
outline: none;
}
/* Fix IE11 */
.fancybox-button div {
height: 100%;
}
.fancybox-button svg {
display: block;
height: 100%;
overflow: visible;
position: relative;
width: 100%;
}
.fancybox-button svg path {
fill: currentColor;
stroke-width: 0;
}
.fancybox-button--play svg:nth-child(2),
.fancybox-button--fsenter svg:nth-child(2) {
display: none;
}
.fancybox-button--pause svg:nth-child(1),
.fancybox-button--fsexit svg:nth-child(1) {
display: none;
}
.fancybox-progress {
background: #ff5268;
height: 2px;
left: 0;
position: absolute;
right: 0;
top: 0;
-ms-transform: scaleX(0);
transform: scaleX(0);
-ms-transform-origin: 0;
transform-origin: 0;
transition-property: transform;
transition-timing-function: linear;
z-index: 99998;
}
/* Close button on the top right corner of html content */
.fancybox-close-small {
background: transparent;
border: 0;
border-radius: 0;
color: #ccc;
cursor: pointer;
opacity: .8;
padding: 8px;
position: absolute;
right: -12px;
top: -44px;
z-index: 401;
}
.fancybox-close-small:hover {
color: #fff;
opacity: 1;
}
.fancybox-slide--html .fancybox-close-small {
color: currentColor;
padding: 10px;
right: 0;
top: 0;
}
.fancybox-slide--image.fancybox-is-scaling .fancybox-content {
overflow: hidden;
}
.fancybox-is-scaling .fancybox-close-small,
.fancybox-is-zoomable.fancybox-can-pan .fancybox-close-small {
display: none;
}
/* Navigation arrows */
.fancybox-navigation .fancybox-button {
background-clip: content-box;
height: 100px;
opacity: 0;
position: absolute;
top: calc(50% - 50px);
width: 70px;
}
.fancybox-navigation .fancybox-button div {
padding: 7px;
}
.fancybox-navigation .fancybox-button--arrow_left {
left: 0;
left: env(safe-area-inset-left);
padding: 31px 26px 31px 6px;
}
.fancybox-navigation .fancybox-button--arrow_right {
padding: 31px 6px 31px 26px;
right: 0;
right: env(safe-area-inset-right);
}
/* Caption */
.fancybox-caption {
background: linear-gradient(to top,
rgba(0, 0, 0, .85) 0%,
rgba(0, 0, 0, .3) 50%,
rgba(0, 0, 0, .15) 65%,
rgba(0, 0, 0, .075) 75.5%,
rgba(0, 0, 0, .037) 82.85%,
rgba(0, 0, 0, .019) 88%,
rgba(0, 0, 0, 0) 100%);
bottom: 0;
color: #eee;
font-size: 14px;
font-weight: 400;
left: 0;
line-height: 1.5;
padding: 75px 44px 25px 44px;
pointer-events: none;
right: 0;
text-align: center;
z-index: 99996;
}
@supports (padding: max(0px)) {
.fancybox-caption {
padding: 75px max(44px, env(safe-area-inset-right)) max(25px, env(safe-area-inset-bottom)) max(44px, env(safe-area-inset-left));
}
}
.fancybox-caption--separate {
margin-top: -50px;
}
.fancybox-caption__body {
max-height: 50vh;
overflow: auto;
pointer-events: all;
}
.fancybox-caption a,
.fancybox-caption a:link,
.fancybox-caption a:visited {
color: #ccc;
text-decoration: none;
}
.fancybox-caption a:hover {
color: #fff;
text-decoration: underline;
}
/* Loading indicator */
.fancybox-loading {
animation: fancybox-rotate 1s linear infinite;
background: transparent;
border: 4px solid #888;
border-bottom-color: #fff;
border-radius: 50%;
height: 50px;
left: 50%;
margin: -25px 0 0 -25px;
opacity: .7;
padding: 0;
position: absolute;
top: 50%;
width: 50px;
z-index: 99999;
}
@keyframes fancybox-rotate {
100% {
transform: rotate(360deg);
}
}
/* Transition effects */
.fancybox-animated {
transition-timing-function: cubic-bezier(0, 0, .25, 1);
}
/* transitionEffect: slide */
.fancybox-fx-slide.fancybox-slide--previous {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.fancybox-fx-slide.fancybox-slide--next {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.fancybox-fx-slide.fancybox-slide--current {
opacity: 1;
transform: translate3d(0, 0, 0);
}
/* transitionEffect: fade */
.fancybox-fx-fade.fancybox-slide--previous,
.fancybox-fx-fade.fancybox-slide--next {
opacity: 0;
transition-timing-function: cubic-bezier(.19, 1, .22, 1);
}
.fancybox-fx-fade.fancybox-slide--current {
opacity: 1;
}
/* transitionEffect: zoom-in-out */
.fancybox-fx-zoom-in-out.fancybox-slide--previous {
opacity: 0;
transform: scale3d(1.5, 1.5, 1.5);
}
.fancybox-fx-zoom-in-out.fancybox-slide--next {
opacity: 0;
transform: scale3d(.5, .5, .5);
}
.fancybox-fx-zoom-in-out.fancybox-slide--current {
opacity: 1;
transform: scale3d(1, 1, 1);
}
/* transitionEffect: rotate */
.fancybox-fx-rotate.fancybox-slide--previous {
opacity: 0;
-ms-transform: rotate(-360deg);
transform: rotate(-360deg);
}
.fancybox-fx-rotate.fancybox-slide--next {
opacity: 0;
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
.fancybox-fx-rotate.fancybox-slide--current {
opacity: 1;
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
/* transitionEffect: circular */
.fancybox-fx-circular.fancybox-slide--previous {
opacity: 0;
transform: scale3d(0, 0, 0) translate3d(-100%, 0, 0);
}
.fancybox-fx-circular.fancybox-slide--next {
opacity: 0;
transform: scale3d(0, 0, 0) translate3d(100%, 0, 0);
}
.fancybox-fx-circular.fancybox-slide--current {
opacity: 1;
transform: scale3d(1, 1, 1) translate3d(0, 0, 0);
}
/* transitionEffect: tube */
.fancybox-fx-tube.fancybox-slide--previous {
transform: translate3d(-100%, 0, 0) scale(.1) skew(-10deg);
}
.fancybox-fx-tube.fancybox-slide--next {
transform: translate3d(100%, 0, 0) scale(.1) skew(10deg);
}
.fancybox-fx-tube.fancybox-slide--current {
transform: translate3d(0, 0, 0) scale(1);
}
/* Styling for Small-Screen Devices */
@media all and (max-height: 576px) {
.fancybox-slide {
padding-left: 6px;
padding-right: 6px;
}
.fancybox-slide--image {
padding: 6px 0;
}
.fancybox-close-small {
right: -6px;
}
.fancybox-slide--image .fancybox-close-small {
background: #4e4e4e;
color: #f2f4f6;
height: 36px;
opacity: 1;
padding: 6px;
right: 0;
top: 0;
width: 36px;
}
.fancybox-caption {
padding-left: 12px;
padding-right: 12px;
}
@supports (padding: max(0px)) {
.fancybox-caption {
padding-left: max(12px, env(safe-area-inset-left));
padding-right: max(12px, env(safe-area-inset-right));
}
}
}
/* Share */
.fancybox-share {
background: #f4f4f4;
border-radius: 3px;
max-width: 90%;
padding: 30px;
text-align: center;
}
.fancybox-share h1 {
color: #222;
font-size: 35px;
font-weight: 700;
margin: 0 0 20px 0;
}
.fancybox-share p {
margin: 0;
padding: 0;
}
.fancybox-share__button {
border: 0;
border-radius: 3px;
display: inline-block;
font-size: 14px;
font-weight: 700;
line-height: 40px;
margin: 0 5px 10px 5px;
min-width: 130px;
padding: 0 15px;
text-decoration: none;
transition: all .2s;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
}
.fancybox-share__button:visited,
.fancybox-share__button:link {
color: #fff;
}
.fancybox-share__button:hover {
text-decoration: none;
}
.fancybox-share__button--fb {
background: #3b5998;
}
.fancybox-share__button--fb:hover {
background: #344e86;
}
.fancybox-share__button--pt {
background: #bd081d;
}
.fancybox-share__button--pt:hover {
background: #aa0719;
}
.fancybox-share__button--tw {
background: #1da1f2;
}
.fancybox-share__button--tw:hover {
background: #0d95e8;
}
.fancybox-share__button svg {
height: 25px;
margin-right: 7px;
position: relative;
top: -1px;
vertical-align: middle;
width: 25px;
}
.fancybox-share__button svg path {
fill: #fff;
}
.fancybox-share__input {
background: transparent;
border: 0;
border-bottom: 1px solid #d7d7d7;
border-radius: 0;
color: #5d5b5b;
font-size: 14px;
margin: 10px 0 0 0;
outline: none;
padding: 10px 15px;
width: 100%;
}
/* Thumbs */
.fancybox-thumbs {
background: #ddd;
bottom: 0;
display: none;
margin: 0;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
padding: 2px 2px 4px 2px;
position: absolute;
right: 0;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
top: 0;
width: 212px;
z-index: 99995;
}
.fancybox-thumbs-x {
overflow-x: auto;
overflow-y: hidden;
}
.fancybox-show-thumbs .fancybox-thumbs {
display: block;
}
.fancybox-show-thumbs .fancybox-inner {
right: 212px;
}
.fancybox-thumbs__list {
font-size: 0;
height: 100%;
list-style: none;
margin: 0;
overflow-x: hidden;
overflow-y: auto;
padding: 0;
position: absolute;
position: relative;
white-space: nowrap;
width: 100%;
}
.fancybox-thumbs-x .fancybox-thumbs__list {
overflow: hidden;
}
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar {
width: 7px;
}
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar-track {
background: #fff;
border-radius: 10px;
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
}
.fancybox-thumbs-y .fancybox-thumbs__list::-webkit-scrollbar-thumb {
background: #2a2a2a;
border-radius: 10px;
}
.fancybox-thumbs__list a {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
background-color: rgba(0, 0, 0, .1);
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
cursor: pointer;
float: left;
height: 75px;
margin: 2px;
max-height: calc(100% - 8px);
max-width: calc(50% - 4px);
outline: none;
overflow: hidden;
padding: 0;
position: relative;
-webkit-tap-highlight-color: transparent;
width: 100px;
}
.fancybox-thumbs__list a::before {
border: 6px solid #ff5268;
bottom: 0;
content: '';
left: 0;
opacity: 0;
position: absolute;
right: 0;
top: 0;
transition: all .2s cubic-bezier(.25, .46, .45, .94);
z-index: 99991;
}
.fancybox-thumbs__list a:focus::before {
opacity: .5;
}
.fancybox-thumbs__list a.fancybox-thumbs-active::before {
opacity: 1;
}
/* Styling for Small-Screen Devices */
@media all and (max-width: 576px) {
.fancybox-thumbs {
width: 110px;
}
.fancybox-show-thumbs .fancybox-inner {
right: 110px;
}
.fancybox-thumbs__list a {
max-width: calc(100% - 10px);
}
}

5632
fancybox/asset/fancybox/jquery.fancybox.js vendored Normal file
View file

@ -0,0 +1,5632 @@
// ==================================================
// fancyBox v3.5.7
//
// Licensed GPLv3 for open source use
// or fancyBox Commercial License for commercial use
//
// http://fancyapps.com/fancybox/
// Copyright 2019 fancyApps
//
// ==================================================
(function (window, document, $, undefined) {
"use strict";
window.console = window.console || {
info: function (stuff) {}
};
// If there's no jQuery, fancyBox can't work
// =========================================
if (!$) {
return;
}
// Check if fancyBox is already initialized
// ========================================
if ($.fn.fancybox) {
console.info("fancyBox already initialized");
return;
}
// Private default settings
// ========================
var defaults = {
// Close existing modals
// Set this to false if you do not need to stack multiple instances
closeExisting: false,
// Enable infinite gallery navigation
loop: false,
// Horizontal space between slides
gutter: 50,
// Enable keyboard navigation
keyboard: true,
// Should allow caption to overlap the content
preventCaptionOverlap: true,
// Should display navigation arrows at the screen edges
arrows: true,
// Should display counter at the top left corner
infobar: true,
// Should display close button (using `btnTpl.smallBtn` template) over the content
// Can be true, false, "auto"
// If "auto" - will be automatically enabled for "html", "inline" or "ajax" items
smallBtn: "auto",
// Should display toolbar (buttons at the top)
// Can be true, false, "auto"
// If "auto" - will be automatically hidden if "smallBtn" is enabled
toolbar: "auto",
// What buttons should appear in the top right corner.
// Buttons will be created using templates from `btnTpl` option
// and they will be placed into toolbar (class="fancybox-toolbar"` element)
buttons: [
"zoom",
//"share",
"slideShow",
//"fullScreen",
//"download",
"thumbs",
"close"
],
// Detect "idle" time in seconds
idleTime: 3,
// Disable right-click and use simple image protection for images
protect: false,
// Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc
modal: false,
image: {
// Wait for images to load before displaying
// true - wait for image to load and then display;
// false - display thumbnail and load the full-sized image over top,
// requires predefined image dimensions (`data-width` and `data-height` attributes)
preload: false
},
ajax: {
// Object containing settings for ajax request
settings: {
// This helps to indicate that request comes from the modal
// Feel free to change naming
data: {
fancybox: true
}
}
},
iframe: {
// Iframe template
tpl: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen="allowfullscreen" allow="autoplay; fullscreen" src=""></iframe>',
// Preload iframe before displaying it
// This allows to calculate iframe content width and height
// (note: Due to "Same Origin Policy", you can't get cross domain data).
preload: true,
// Custom CSS styling for iframe wrapping element
// You can use this to set custom iframe dimensions
css: {},
// Iframe tag attributes
attr: {
scrolling: "auto"
}
},
// For HTML5 video only
video: {
tpl: '<video class="fancybox-video" controls controlsList="nodownload" poster="{{poster}}">' +
'<source src="{{src}}" type="{{format}}" />' +
'Sorry, your browser doesn\'t support embedded videos, <a href="{{src}}">download</a> and watch with your favorite video player!' +
"</video>",
format: "", // custom video format
autoStart: true
},
// Default content type if cannot be detected automatically
defaultType: "image",
// Open/close animation type
// Possible values:
// false - disable
// "zoom" - zoom images from/to thumbnail
// "fade"
// "zoom-in-out"
//
animationEffect: "zoom",
// Duration in ms for open/close animation
animationDuration: 366,
// Should image change opacity while zooming
// If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios
zoomOpacity: "auto",
// Transition effect between slides
//
// Possible values:
// false - disable
// "fade'
// "slide'
// "circular'
// "tube'
// "zoom-in-out'
// "rotate'
//
transitionEffect: "fade",
// Duration in ms for transition animation
transitionDuration: 366,
// Custom CSS class for slide element
slideClass: "",
// Custom CSS class for layout
baseClass: "",
// Base template for layout
baseTpl: '<div class="fancybox-container" role="dialog" tabindex="-1">' +
'<div class="fancybox-bg"></div>' +
'<div class="fancybox-inner">' +
'<div class="fancybox-infobar"><span data-fancybox-index></span>&nbsp;/&nbsp;<span data-fancybox-count></span></div>' +
'<div class="fancybox-toolbar">{{buttons}}</div>' +
'<div class="fancybox-navigation">{{arrows}}</div>' +
'<div class="fancybox-stage"></div>' +
'<div class="fancybox-caption"><div class="fancybox-caption__body"></div></div>' +
"</div>" +
"</div>",
// Loading indicator template
spinnerTpl: '<div class="fancybox-loading"></div>',
// Error message template
errorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>',
btnTpl: {
download: '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg>' +
"</a>",
zoom: '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg>' +
"</button>",
close: '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +
"</button>",
// Arrows
arrowLeft: '<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' +
'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div>' +
"</button>",
arrowRight: '<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' +
'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div>' +
"</button>",
// This small close button will be appended to your html/inline/ajax content by default,
// if "smallBtn" option is not set to false
smallBtn: '<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg>' +
"</button>"
},
// Container is injected into this element
parentEl: "body",
// Hide browser vertical scrollbars; use at your own risk
hideScrollbar: true,
// Focus handling
// ==============
// Try to focus on the first focusable element after opening
autoFocus: true,
// Put focus back to active element after closing
backFocus: true,
// Do not let user to focus on element outside modal content
trapFocus: true,
// Module specific options
// =======================
fullScreen: {
autoStart: false
},
// Set `touch: false` to disable panning/swiping
touch: {
vertical: true, // Allow to drag content vertically
momentum: true // Continue movement after releasing mouse/touch when panning
},
// Hash value when initializing manually,
// set `false` to disable hash change
hash: null,
// Customize or add new media types
// Example:
/*
media : {
youtube : {
params : {
autoplay : 0
}
}
}
*/
media: {},
slideShow: {
autoStart: false,
speed: 3000
},
thumbs: {
autoStart: false, // Display thumbnails on opening
hideOnClose: true, // Hide thumbnail grid when closing animation starts
parentEl: ".fancybox-container", // Container is injected into this element
axis: "y" // Vertical (y) or horizontal (x) scrolling
},
// Use mousewheel to navigate gallery
// If 'auto' - enabled for images only
wheel: "auto",
// Callbacks
//==========
// See Documentation/API/Events for more information
// Example:
/*
afterShow: function( instance, current ) {
console.info( 'Clicked element:' );
console.info( current.opts.$orig );
}
*/
onInit: $.noop, // When instance has been initialized
beforeLoad: $.noop, // Before the content of a slide is being loaded
afterLoad: $.noop, // When the content of a slide is done loading
beforeShow: $.noop, // Before open animation starts
afterShow: $.noop, // When content is done loading and animating
beforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.
afterClose: $.noop, // After instance has been closed
onActivate: $.noop, // When instance is brought to front
onDeactivate: $.noop, // When other instance has been activated
// Interaction
// ===========
// Use options below to customize taken action when user clicks or double clicks on the fancyBox area,
// each option can be string or method that returns value.
//
// Possible values:
// "close" - close instance
// "next" - move to next gallery item
// "nextOrClose" - move to next gallery item or close if gallery has only one item
// "toggleControls" - show/hide controls
// "zoom" - zoom image (if loaded)
// false - do nothing
// Clicked on the content
clickContent: function (current, event) {
return current.type === "image" ? "zoom" : false;
},
// Clicked on the slide
clickSlide: "close",
// Clicked on the background (backdrop) element;
// if you have not changed the layout, then most likely you need to use `clickSlide` option
clickOutside: "close",
// Same as previous two, but for double click
dblclickContent: false,
dblclickSlide: false,
dblclickOutside: false,
// Custom options when mobile device is detected
// =============================================
mobile: {
preventCaptionOverlap: false,
idleTime: false,
clickContent: function (current, event) {
return current.type === "image" ? "toggleControls" : false;
},
clickSlide: function (current, event) {
return current.type === "image" ? "toggleControls" : "close";
},
dblclickContent: function (current, event) {
return current.type === "image" ? "zoom" : false;
},
dblclickSlide: function (current, event) {
return current.type === "image" ? "zoom" : false;
}
},
// Internationalization
// ====================
lang: "en",
i18n: {
en: {
CLOSE: "Close",
NEXT: "Next",
PREV: "Previous",
ERROR: "The requested content cannot be loaded. <br/> Please try again later.",
PLAY_START: "Start slideshow",
PLAY_STOP: "Pause slideshow",
FULL_SCREEN: "Full screen",
THUMBS: "Thumbnails",
DOWNLOAD: "Download",
SHARE: "Share",
ZOOM: "Zoom"
},
de: {
CLOSE: "Schlie&szlig;en",
NEXT: "Weiter",
PREV: "Zur&uuml;ck",
ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es sp&auml;ter nochmal.",
PLAY_START: "Diaschau starten",
PLAY_STOP: "Diaschau beenden",
FULL_SCREEN: "Vollbild",
THUMBS: "Vorschaubilder",
DOWNLOAD: "Herunterladen",
SHARE: "Teilen",
ZOOM: "Vergr&ouml;&szlig;ern"
}
}
};
// Few useful variables and methods
// ================================
var $W = $(window);
var $D = $(document);
var called = 0;
// Check if an object is a jQuery object and not a native JavaScript object
// ========================================================================
var isQuery = function (obj) {
return obj && obj.hasOwnProperty && obj instanceof $;
};
// Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"
// ===============================================================================
var requestAFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
// if all else fails, use setTimeout
function (callback) {
return window.setTimeout(callback, 1000 / 60);
}
);
})();
var cancelAFrame = (function () {
return (
window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
function (id) {
window.clearTimeout(id);
}
);
})();
// Detect the supported transition-end event property name
// =======================================================
var transitionEnd = (function () {
var el = document.createElement("fakeelement"),
t;
var transitions = {
transition: "transitionend",
OTransition: "oTransitionEnd",
MozTransition: "transitionend",
WebkitTransition: "webkitTransitionEnd"
};
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
return "transitionend";
})();
// Force redraw on an element.
// This helps in cases where the browser doesn't redraw an updated element properly
// ================================================================================
var forceRedraw = function ($el) {
return $el && $el.length && $el[0].offsetHeight;
};
// Exclude array (`buttons`) options from deep merging
// ===================================================
var mergeOpts = function (opts1, opts2) {
var rez = $.extend(true, {}, opts1, opts2);
$.each(opts2, function (key, value) {
if ($.isArray(value)) {
rez[key] = value;
}
});
return rez;
};
// How much of an element is visible in viewport
// =============================================
var inViewport = function (elem) {
var elemCenter, rez;
if (!elem || elem.ownerDocument !== document) {
return false;
}
$(".fancybox-container").css("pointer-events", "none");
elemCenter = {
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
};
rez = document.elementFromPoint(elemCenter.x, elemCenter.y) === elem;
$(".fancybox-container").css("pointer-events", "");
return rez;
};
// Class definition
// ================
var FancyBox = function (content, opts, index) {
var self = this;
self.opts = mergeOpts({
index: index
}, $.fancybox.defaults);
if ($.isPlainObject(opts)) {
self.opts = mergeOpts(self.opts, opts);
}
if ($.fancybox.isMobile) {
self.opts = mergeOpts(self.opts, self.opts.mobile);
}
self.id = self.opts.id || ++called;
self.currIndex = parseInt(self.opts.index, 10) || 0;
self.prevIndex = null;
self.prevPos = null;
self.currPos = 0;
self.firstRun = true;
// All group items
self.group = [];
// Existing slides (for current, next and previous gallery items)
self.slides = {};
// Create group elements
self.addContent(content);
if (!self.group.length) {
return;
}
self.init();
};
$.extend(FancyBox.prototype, {
// Create DOM structure
// ====================
init: function () {
var self = this,
firstItem = self.group[self.currIndex],
firstItemOpts = firstItem.opts,
$container,
buttonStr;
if (firstItemOpts.closeExisting) {
$.fancybox.close(true);
}
// Hide scrollbars
// ===============
$("body").addClass("fancybox-active");
if (
!$.fancybox.getInstance() &&
firstItemOpts.hideScrollbar !== false &&
!$.fancybox.isMobile &&
document.body.scrollHeight > window.innerHeight
) {
$("head").append(
'<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:' +
(window.innerWidth - document.documentElement.clientWidth) +
"px;}</style>"
);
$("body").addClass("compensate-for-scrollbar");
}
// Build html markup and set references
// ====================================
// Build html code for buttons and insert into main template
buttonStr = "";
$.each(firstItemOpts.buttons, function (index, value) {
buttonStr += firstItemOpts.btnTpl[value] || "";
});
// Create markup from base template, it will be initially hidden to
// avoid unnecessary work like painting while initializing is not complete
$container = $(
self.translate(
self,
firstItemOpts.baseTpl
.replace("{{buttons}}", buttonStr)
.replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight)
)
)
.attr("id", "fancybox-container-" + self.id)
.addClass(firstItemOpts.baseClass)
.data("FancyBox", self)
.appendTo(firstItemOpts.parentEl);
// Create object holding references to jQuery wrapped nodes
self.$refs = {
container: $container
};
["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function (item) {
self.$refs[item] = $container.find(".fancybox-" + item);
});
self.trigger("onInit");
// Enable events, deactive previous instances
self.activate();
// Build slides, load and reveal content
self.jumpTo(self.currIndex);
},
// Simple i18n support - replaces object keys found in template
// with corresponding values
// ============================================================
translate: function (obj, str) {
var arr = obj.opts.i18n[obj.opts.lang] || obj.opts.i18n.en;
return str.replace(/\{\{(\w+)\}\}/g, function (match, n) {
return arr[n] === undefined ? match : arr[n];
});
},
// Populate current group with fresh content
// Check if each object has valid type and content
// ===============================================
addContent: function (content) {
var self = this,
items = $.makeArray(content),
thumbs;
$.each(items, function (i, item) {
var obj = {},
opts = {},
$item,
type,
found,
src,
srcParts;
// Step 1 - Make sure we have an object
// ====================================
if ($.isPlainObject(item)) {
// We probably have manual usage here, something like
// $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )
obj = item;
opts = item.opts || item;
} else if ($.type(item) === "object" && $(item).length) {
// Here we probably have jQuery collection returned by some selector
$item = $(item);
// Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'`
opts = $item.data() || {};
opts = $.extend(true, {}, opts, opts.options);
// Here we store clicked element
opts.$orig = $item;
obj.src = self.opts.src || opts.src || $item.attr("href");
// Assume that simple syntax is used, for example:
// `$.fancybox.open( $("#test"), {} );`
if (!obj.type && !obj.src) {
obj.type = "inline";
obj.src = item;
}
} else {
// Assume we have a simple html code, for example:
// $.fancybox.open( '<div><h1>Hi!</h1></div>' );
obj = {
type: "html",
src: item + ""
};
}
// Each gallery object has full collection of options
obj.opts = $.extend(true, {}, self.opts, opts);
// Do not merge buttons array
if ($.isArray(opts.buttons)) {
obj.opts.buttons = opts.buttons;
}
if ($.fancybox.isMobile && obj.opts.mobile) {
obj.opts = mergeOpts(obj.opts, obj.opts.mobile);
}
// Step 2 - Make sure we have content type, if not - try to guess
// ==============================================================
type = obj.type || obj.opts.type;
src = obj.src || "";
if (!type && src) {
if ((found = src.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))) {
type = "video";
if (!obj.opts.video.format) {
obj.opts.video.format = "video/" + (found[1] === "ogv" ? "ogg" : found[1]);
}
} else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {
type = "image";
} else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {
type = "iframe";
obj = $.extend(true, obj, {
contentType: "pdf",
opts: {
iframe: {
preload: false
}
}
});
} else if (src.charAt(0) === "#") {
type = "inline";
}
}
if (type) {
obj.type = type;
} else {
self.trigger("objectNeedsType", obj);
}
if (!obj.contentType) {
obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type;
}
// Step 3 - Some adjustments
// =========================
obj.index = self.group.length;
if (obj.opts.smallBtn == "auto") {
obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1;
}
if (obj.opts.toolbar === "auto") {
obj.opts.toolbar = !obj.opts.smallBtn;
}
// Find thumbnail image, check if exists and if is in the viewport
obj.$thumb = obj.opts.$thumb || null;
if (obj.opts.$trigger && obj.index === self.opts.index) {
obj.$thumb = obj.opts.$trigger.find("img:first");
if (obj.$thumb.length) {
obj.opts.$orig = obj.opts.$trigger;
}
}
if (!(obj.$thumb && obj.$thumb.length) && obj.opts.$orig) {
obj.$thumb = obj.opts.$orig.find("img:first");
}
if (obj.$thumb && !obj.$thumb.length) {
obj.$thumb = null;
}
obj.thumb = obj.opts.thumb || (obj.$thumb ? obj.$thumb[0].src : null);
// "caption" is a "special" option, it can be used to customize caption per gallery item
if ($.type(obj.opts.caption) === "function") {
obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);
}
if ($.type(self.opts.caption) === "function") {
obj.opts.caption = self.opts.caption.apply(item, [self, obj]);
}
// Make sure we have caption as a string or jQuery object
if (!(obj.opts.caption instanceof $)) {
obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + "";
}
// Check if url contains "filter" used to filter the content
// Example: "ajax.html #something"
if (obj.type === "ajax") {
srcParts = src.split(/\s+/, 2);
if (srcParts.length > 1) {
obj.src = srcParts.shift();
obj.opts.filter = srcParts.shift();
}
}
// Hide all buttons and disable interactivity for modal items
if (obj.opts.modal) {
obj.opts = $.extend(true, obj.opts, {
trapFocus: true,
// Remove buttons
infobar: 0,
toolbar: 0,
smallBtn: 0,
// Disable keyboard navigation
keyboard: 0,
// Disable some modules
slideShow: 0,
fullScreen: 0,
thumbs: 0,
touch: 0,
// Disable click event handlers
clickContent: false,
clickSlide: false,
clickOutside: false,
dblclickContent: false,
dblclickSlide: false,
dblclickOutside: false
});
}
// Step 4 - Add processed object to group
// ======================================
self.group.push(obj);
});
// Update controls if gallery is already opened
if (Object.keys(self.slides).length) {
self.updateControls();
// Update thumbnails, if needed
thumbs = self.Thumbs;
if (thumbs && thumbs.isActive) {
thumbs.create();
thumbs.focus();
}
}
},
// Attach an event handler functions for:
// - navigation buttons
// - browser scrolling, resizing;
// - focusing
// - keyboard
// - detecting inactivity
// ======================================
addEvents: function () {
var self = this;
self.removeEvents();
// Make navigation elements clickable
// ==================================
self.$refs.container
.on("click.fb-close", "[data-fancybox-close]", function (e) {
e.stopPropagation();
e.preventDefault();
self.close(e);
})
.on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function (e) {
e.stopPropagation();
e.preventDefault();
self.previous();
})
.on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function (e) {
e.stopPropagation();
e.preventDefault();
self.next();
})
.on("click.fb", "[data-fancybox-zoom]", function (e) {
// Click handler for zoom button
self[self.isScaledDown() ? "scaleToActual" : "scaleToFit"]();
});
// Handle page scrolling and browser resizing
// ==========================================
$W.on("orientationchange.fb resize.fb", function (e) {
if (e && e.originalEvent && e.originalEvent.type === "resize") {
if (self.requestId) {
cancelAFrame(self.requestId);
}
self.requestId = requestAFrame(function () {
self.update(e);
});
} else {
if (self.current && self.current.type === "iframe") {
self.$refs.stage.hide();
}
setTimeout(
function () {
self.$refs.stage.show();
self.update(e);
},
$.fancybox.isMobile ? 600 : 250
);
}
});
$D.on("keydown.fb", function (e) {
var instance = $.fancybox ? $.fancybox.getInstance() : null,
current = instance.current,
keycode = e.keyCode || e.which;
// Trap keyboard focus inside of the modal
// =======================================
if (keycode == 9) {
if (current.opts.trapFocus) {
self.focus(e);
}
return;
}
// Enable keyboard navigation
// ==========================
if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input,textarea,video,audio,select")) {
return;
}
// Backspace and Esc keys
if (keycode === 8 || keycode === 27) {
e.preventDefault();
self.close(e);
return;
}
// Left arrow and Up arrow
if (keycode === 37 || keycode === 38) {
e.preventDefault();
self.previous();
return;
}
// Righ arrow and Down arrow
if (keycode === 39 || keycode === 40) {
e.preventDefault();
self.next();
return;
}
self.trigger("afterKeydown", e, keycode);
});
// Hide controls after some inactivity period
if (self.group[self.currIndex].opts.idleTime) {
self.idleSecondsCounter = 0;
$D.on(
"mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",
function (e) {
self.idleSecondsCounter = 0;
if (self.isIdle) {
self.showControls();
}
self.isIdle = false;
}
);
self.idleInterval = window.setInterval(function () {
self.idleSecondsCounter++;
if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {
self.isIdle = true;
self.idleSecondsCounter = 0;
self.hideControls();
}
}, 1000);
}
},
// Remove events added by the core
// ===============================
removeEvents: function () {
var self = this;
$W.off("orientationchange.fb resize.fb");
$D.off("keydown.fb .fb-idle");
this.$refs.container.off(".fb-close .fb-prev .fb-next");
if (self.idleInterval) {
window.clearInterval(self.idleInterval);
self.idleInterval = null;
}
},
// Change to previous gallery item
// ===============================
previous: function (duration) {
return this.jumpTo(this.currPos - 1, duration);
},
// Change to next gallery item
// ===========================
next: function (duration) {
return this.jumpTo(this.currPos + 1, duration);
},
// Switch to selected gallery item
// ===============================
jumpTo: function (pos, duration) {
var self = this,
groupLen = self.group.length,
firstRun,
isMoved,
loop,
current,
previous,
slidePos,
stagePos,
prop,
diff;
if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {
return;
}
// Should loop?
pos = parseInt(pos, 10);
loop = self.current ? self.current.opts.loop : self.opts.loop;
if (!loop && (pos < 0 || pos >= groupLen)) {
return false;
}
// Check if opening for the first time; this helps to speed things up
firstRun = self.firstRun = !Object.keys(self.slides).length;
// Create slides
previous = self.current;
self.prevIndex = self.currIndex;
self.prevPos = self.currPos;
current = self.createSlide(pos);
if (groupLen > 1) {
if (loop || current.index < groupLen - 1) {
self.createSlide(pos + 1);
}
if (loop || current.index > 0) {
self.createSlide(pos - 1);
}
}
self.current = current;
self.currIndex = current.index;
self.currPos = current.pos;
self.trigger("beforeShow", firstRun);
self.updateControls();
// Validate duration length
current.forcedDuration = undefined;
if ($.isNumeric(duration)) {
current.forcedDuration = duration;
} else {
duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"];
}
duration = parseInt(duration, 10);
// Check if user has swiped the slides or if still animating
isMoved = self.isMoved(current);
// Make sure current slide is visible
current.$slide.addClass("fancybox-slide--current");
// Fresh start - reveal container, current slide and start loading content
if (firstRun) {
if (current.opts.animationEffect && duration) {
self.$refs.container.css("transition-duration", duration + "ms");
}
self.$refs.container.addClass("fancybox-is-open").trigger("focus");
// Attempt to load content into slide
// This will later call `afterLoad` -> `revealContent`
self.loadSlide(current);
self.preload("image");
return;
}
// Get actual slide/stage positions (before cleaning up)
slidePos = $.fancybox.getTranslate(previous.$slide);
stagePos = $.fancybox.getTranslate(self.$refs.stage);
// Clean up all slides
$.each(self.slides, function (index, slide) {
$.fancybox.stop(slide.$slide, true);
});
if (previous.pos !== current.pos) {
previous.isComplete = false;
}
previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current");
// If slides are out of place, then animate them to correct position
if (isMoved) {
// Calculate horizontal swipe distance
diff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);
$.each(self.slides, function (index, slide) {
slide.$slide.removeClass("fancybox-animated").removeClass(function (index, className) {
return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
});
// Make sure that each slide is in equal distance
// This is mostly needed for freshly added slides, because they are not yet positioned
var leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;
$.fancybox.setTranslate(slide.$slide, {
top: 0,
left: leftPos - stagePos.left + diff
});
if (slide.pos !== current.pos) {
slide.$slide.addClass("fancybox-slide--" + (slide.pos > current.pos ? "next" : "previous"));
}
// Redraw to make sure that transition will start
forceRedraw(slide.$slide);
// Animate the slide
$.fancybox.animate(
slide.$slide, {
top: 0,
left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter
},
duration,
function () {
slide.$slide
.css({
transform: "",
opacity: ""
})
.removeClass("fancybox-slide--next fancybox-slide--previous");
if (slide.pos === self.currPos) {
self.complete();
}
}
);
});
} else if (duration && current.opts.transitionEffect) {
// Set transition effect for previously active slide
prop = "fancybox-animated fancybox-fx-" + current.opts.transitionEffect;
previous.$slide.addClass("fancybox-slide--" + (previous.pos > current.pos ? "next" : "previous"));
$.fancybox.animate(
previous.$slide,
prop,
duration,
function () {
previous.$slide.removeClass(prop).removeClass("fancybox-slide--next fancybox-slide--previous");
},
false
);
}
if (current.isLoaded) {
self.revealContent(current);
} else {
self.loadSlide(current);
}
self.preload("image");
},
// Create new "slide" element
// These are gallery items that are actually added to DOM
// =======================================================
createSlide: function (pos) {
var self = this,
$slide,
index;
index = pos % self.group.length;
index = index < 0 ? self.group.length + index : index;
if (!self.slides[pos] && self.group[index]) {
$slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);
self.slides[pos] = $.extend(true, {}, self.group[index], {
pos: pos,
$slide: $slide,
isLoaded: false
});
self.updateSlide(self.slides[pos]);
}
return self.slides[pos];
},
// Scale image to the actual size of the image;
// x and y values should be relative to the slide
// ==============================================
scaleToActual: function (x, y, duration) {
var self = this,
current = self.current,
$content = current.$content,
canvasWidth = $.fancybox.getTranslate(current.$slide).width,
canvasHeight = $.fancybox.getTranslate(current.$slide).height,
newImgWidth = current.width,
newImgHeight = current.height,
imgPos,
posX,
posY,
scaleX,
scaleY;
if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
return;
}
self.isAnimating = true;
$.fancybox.stop($content);
x = x === undefined ? canvasWidth * 0.5 : x;
y = y === undefined ? canvasHeight * 0.5 : y;
imgPos = $.fancybox.getTranslate($content);
imgPos.top -= $.fancybox.getTranslate(current.$slide).top;
imgPos.left -= $.fancybox.getTranslate(current.$slide).left;
scaleX = newImgWidth / imgPos.width;
scaleY = newImgHeight / imgPos.height;
// Get center position for original image
posX = canvasWidth * 0.5 - newImgWidth * 0.5;
posY = canvasHeight * 0.5 - newImgHeight * 0.5;
// Make sure image does not move away from edges
if (newImgWidth > canvasWidth) {
posX = imgPos.left * scaleX - (x * scaleX - x);
if (posX > 0) {
posX = 0;
}
if (posX < canvasWidth - newImgWidth) {
posX = canvasWidth - newImgWidth;
}
}
if (newImgHeight > canvasHeight) {
posY = imgPos.top * scaleY - (y * scaleY - y);
if (posY > 0) {
posY = 0;
}
if (posY < canvasHeight - newImgHeight) {
posY = canvasHeight - newImgHeight;
}
}
self.updateCursor(newImgWidth, newImgHeight);
$.fancybox.animate(
$content, {
top: posY,
left: posX,
scaleX: scaleX,
scaleY: scaleY
},
duration || 366,
function () {
self.isAnimating = false;
}
);
// Stop slideshow
if (self.SlideShow && self.SlideShow.isActive) {
self.SlideShow.stop();
}
},
// Scale image to fit inside parent element
// ========================================
scaleToFit: function (duration) {
var self = this,
current = self.current,
$content = current.$content,
end;
if (self.isAnimating || self.isMoved() || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {
return;
}
self.isAnimating = true;
$.fancybox.stop($content);
end = self.getFitPos(current);
self.updateCursor(end.width, end.height);
$.fancybox.animate(
$content, {
top: end.top,
left: end.left,
scaleX: end.width / $content.width(),
scaleY: end.height / $content.height()
},
duration || 366,
function () {
self.isAnimating = false;
}
);
},
// Calculate image size to fit inside viewport
// ===========================================
getFitPos: function (slide) {
var self = this,
$content = slide.$content,
$slide = slide.$slide,
width = slide.width || slide.opts.width,
height = slide.height || slide.opts.height,
maxWidth,
maxHeight,
minRatio,
aspectRatio,
rez = {};
if (!slide.isLoaded || !$content || !$content.length) {
return false;
}
maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;
maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;
maxWidth -=
parseFloat($slide.css("paddingLeft")) +
parseFloat($slide.css("paddingRight")) +
parseFloat($content.css("marginLeft")) +
parseFloat($content.css("marginRight"));
maxHeight -=
parseFloat($slide.css("paddingTop")) +
parseFloat($slide.css("paddingBottom")) +
parseFloat($content.css("marginTop")) +
parseFloat($content.css("marginBottom"));
if (!width || !height) {
width = maxWidth;
height = maxHeight;
}
minRatio = Math.min(1, maxWidth / width, maxHeight / height);
width = minRatio * width;
height = minRatio * height;
// Adjust width/height to precisely fit into container
if (width > maxWidth - 0.5) {
width = maxWidth;
}
if (height > maxHeight - 0.5) {
height = maxHeight;
}
if (slide.type === "image") {
rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css("paddingTop"));
rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css("paddingLeft"));
} else if (slide.contentType === "video") {
// Force aspect ratio for the video
// "I say the whole world must learn of our peaceful ways… by force!"
aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;
if (height > width / aspectRatio) {
height = width / aspectRatio;
} else if (width > height * aspectRatio) {
width = height * aspectRatio;
}
}
rez.width = width;
rez.height = height;
return rez;
},
// Update content size and position for all slides
// ==============================================
update: function (e) {
var self = this;
$.each(self.slides, function (key, slide) {
self.updateSlide(slide, e);
});
},
// Update slide content position and size
// ======================================
updateSlide: function (slide, e) {
var self = this,
$content = slide && slide.$content,
width = slide.width || slide.opts.width,
height = slide.height || slide.opts.height,
$slide = slide.$slide;
// First, prevent caption overlap, if needed
self.adjustCaption(slide);
// Then resize content to fit inside the slide
if ($content && (width || height || slide.contentType === "video") && !slide.hasError) {
$.fancybox.stop($content);
$.fancybox.setTranslate($content, self.getFitPos(slide));
if (slide.pos === self.currPos) {
self.isAnimating = false;
self.updateCursor();
}
}
// Then some adjustments
self.adjustLayout(slide);
if ($slide.length) {
$slide.trigger("refresh");
if (slide.pos === self.currPos) {
self.$refs.toolbar
.add(self.$refs.navigation.find(".fancybox-button--arrow_right"))
.toggleClass("compensate-for-scrollbar", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);
}
}
self.trigger("onUpdate", slide, e);
},
// Horizontally center slide
// =========================
centerSlide: function (duration) {
var self = this,
current = self.current,
$slide = current.$slide;
if (self.isClosing || !current) {
return;
}
$slide.siblings().css({
transform: "",
opacity: ""
});
$slide
.parent()
.children()
.removeClass("fancybox-slide--previous fancybox-slide--next");
$.fancybox.animate(
$slide, {
top: 0,
left: 0,
opacity: 1
},
duration === undefined ? 0 : duration,
function () {
// Clean up
$slide.css({
transform: "",
opacity: ""
});
if (!current.isComplete) {
self.complete();
}
},
false
);
},
// Check if current slide is moved (swiped)
// ========================================
isMoved: function (slide) {
var current = slide || this.current,
slidePos,
stagePos;
if (!current) {
return false;
}
stagePos = $.fancybox.getTranslate(this.$refs.stage);
slidePos = $.fancybox.getTranslate(current.$slide);
return (
!current.$slide.hasClass("fancybox-animated") &&
(Math.abs(slidePos.top - stagePos.top) > 0.5 || Math.abs(slidePos.left - stagePos.left) > 0.5)
);
},
// Update cursor style depending if content can be zoomed
// ======================================================
updateCursor: function (nextWidth, nextHeight) {
var self = this,
current = self.current,
$container = self.$refs.container,
canPan,
isZoomable;
if (!current || self.isClosing || !self.Guestures) {
return;
}
$container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan");
canPan = self.canPan(nextWidth, nextHeight);
isZoomable = canPan ? true : self.isZoomable();
$container.toggleClass("fancybox-is-zoomable", isZoomable);
$("[data-fancybox-zoom]").prop("disabled", !isZoomable);
if (canPan) {
$container.addClass("fancybox-can-pan");
} else if (
isZoomable &&
(current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == "zoom"))
) {
$container.addClass("fancybox-can-zoomIn");
} else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== "video") {
$container.addClass("fancybox-can-swipe");
}
},
// Check if current slide is zoomable
// ==================================
isZoomable: function () {
var self = this,
current = self.current,
fitPos;
// Assume that slide is zoomable if:
// - image is still loading
// - actual size of the image is smaller than available area
if (current && !self.isClosing && current.type === "image" && !current.hasError) {
if (!current.isLoaded) {
return true;
}
fitPos = self.getFitPos(current);
if (fitPos && (current.width > fitPos.width || current.height > fitPos.height)) {
return true;
}
}
return false;
},
// Check if current image dimensions are smaller than actual
// =========================================================
isScaledDown: function (nextWidth, nextHeight) {
var self = this,
rez = false,
current = self.current,
$content = current.$content;
if (nextWidth !== undefined && nextHeight !== undefined) {
rez = nextWidth < current.width && nextHeight < current.height;
} else if ($content) {
rez = $.fancybox.getTranslate($content);
rez = rez.width < current.width && rez.height < current.height;
}
return rez;
},
// Check if image dimensions exceed parent element
// ===============================================
canPan: function (nextWidth, nextHeight) {
var self = this,
current = self.current,
pos = null,
rez = false;
if (current.type === "image" && (current.isComplete || (nextWidth && nextHeight)) && !current.hasError) {
rez = self.getFitPos(current);
if (nextWidth !== undefined && nextHeight !== undefined) {
pos = {
width: nextWidth,
height: nextHeight
};
} else if (current.isComplete) {
pos = $.fancybox.getTranslate(current.$content);
}
if (pos && rez) {
rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;
}
}
return rez;
},
// Load content into the slide
// ===========================
loadSlide: function (slide) {
var self = this,
type,
$slide,
ajaxLoad;
if (slide.isLoading || slide.isLoaded) {
return;
}
slide.isLoading = true;
if (self.trigger("beforeLoad", slide) === false) {
slide.isLoading = false;
return false;
}
type = slide.type;
$slide = slide.$slide;
$slide
.off("refresh")
.trigger("onReset")
.addClass(slide.opts.slideClass);
// Create content depending on the type
switch (type) {
case "image":
self.setImage(slide);
break;
case "iframe":
self.setIframe(slide);
break;
case "html":
self.setContent(slide, slide.src || slide.content);
break;
case "video":
self.setContent(
slide,
slide.opts.video.tpl
.replace(/\{\{src\}\}/gi, slide.src)
.replace("{{format}}", slide.opts.videoFormat || slide.opts.video.format || "")
.replace("{{poster}}", slide.thumb || "")
);
break;
case "inline":
if ($(slide.src).length) {
self.setContent(slide, $(slide.src));
} else {
self.setError(slide);
}
break;
case "ajax":
self.showLoading(slide);
ajaxLoad = $.ajax(
$.extend({}, slide.opts.ajax.settings, {
url: slide.src,
success: function (data, textStatus) {
if (textStatus === "success") {
self.setContent(slide, data);
}
},
error: function (jqXHR, textStatus) {
if (jqXHR && textStatus !== "abort") {
self.setError(slide);
}
}
})
);
$slide.one("onReset", function () {
ajaxLoad.abort();
});
break;
default:
self.setError(slide);
break;
}
return true;
},
// Use thumbnail image, if possible
// ================================
setImage: function (slide) {
var self = this,
ghost;
// Check if need to show loading icon
setTimeout(function () {
var $img = slide.$image;
if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {
self.showLoading(slide);
}
}, 50);
//Check if image has srcset
self.checkSrcset(slide);
// This will be wrapper containing both ghost and actual image
slide.$content = $('<div class="fancybox-content"></div>')
.addClass("fancybox-is-hidden")
.appendTo(slide.$slide.addClass("fancybox-slide--image"));
// If we have a thumbnail, we can display it while actual image is loading
// Users will not stare at black screen and actual image will appear gradually
if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && slide.thumb) {
slide.width = slide.opts.width;
slide.height = slide.opts.height;
ghost = document.createElement("img");
ghost.onerror = function () {
$(this).remove();
slide.$ghost = null;
};
ghost.onload = function () {
self.afterLoad(slide);
};
slide.$ghost = $(ghost)
.addClass("fancybox-image")
.appendTo(slide.$content)
.attr("src", slide.thumb);
}
// Start loading actual image
self.setBigImage(slide);
},
// Check if image has srcset and get the source
// ============================================
checkSrcset: function (slide) {
var srcset = slide.opts.srcset || slide.opts.image.srcset,
found,
temp,
pxRatio,
windowWidth;
// If we have "srcset", then we need to find first matching "src" value.
// This is necessary, because when you set an src attribute, the browser will preload the image
// before any javascript or even CSS is applied.
if (srcset) {
pxRatio = window.devicePixelRatio || 1;
windowWidth = window.innerWidth * pxRatio;
temp = srcset.split(",").map(function (el) {
var ret = {};
el.trim()
.split(/\s+/)
.forEach(function (el, i) {
var value = parseInt(el.substring(0, el.length - 1), 10);
if (i === 0) {
return (ret.url = el);
}
if (value) {
ret.value = value;
ret.postfix = el[el.length - 1];
}
});
return ret;
});
// Sort by value
temp.sort(function (a, b) {
return a.value - b.value;
});
// Ok, now we have an array of all srcset values
for (var j = 0; j < temp.length; j++) {
var el = temp[j];
if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) {
found = el;
break;
}
}
// If not found, take the last one
if (!found && temp.length) {
found = temp[temp.length - 1];
}
if (found) {
slide.src = found.url;
// If we have default width/height values, we can calculate height for matching source
if (slide.width && slide.height && found.postfix == "w") {
slide.height = (slide.width / slide.height) * found.value;
slide.width = found.value;
}
slide.opts.srcset = srcset;
}
}
},
// Create full-size image
// ======================
setBigImage: function (slide) {
var self = this,
img = document.createElement("img"),
$img = $(img);
slide.$image = $img
.one("error", function () {
self.setError(slide);
})
.one("load", function () {
var sizes;
if (!slide.$ghost) {
self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);
self.afterLoad(slide);
}
if (self.isClosing) {
return;
}
if (slide.opts.srcset) {
sizes = slide.opts.sizes;
if (!sizes || sizes === "auto") {
sizes =
(slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round((slide.width / slide.height) * 100)) +
"vw";
}
$img.attr("sizes", sizes).attr("srcset", slide.opts.srcset);
}
// Hide temporary image after some delay
if (slide.$ghost) {
setTimeout(function () {
if (slide.$ghost && !self.isClosing) {
slide.$ghost.hide();
}
}, Math.min(300, Math.max(1000, slide.height / 1600)));
}
self.hideLoading(slide);
})
.addClass("fancybox-image")
.attr("src", slide.src)
.appendTo(slide.$content);
if ((img.complete || img.readyState == "complete") && $img.naturalWidth && $img.naturalHeight) {
$img.trigger("load");
} else if (img.error) {
$img.trigger("error");
}
},
// Computes the slide size from image size and maxWidth/maxHeight
// ==============================================================
resolveImageSlideSize: function (slide, imgWidth, imgHeight) {
var maxWidth = parseInt(slide.opts.width, 10),
maxHeight = parseInt(slide.opts.height, 10);
// Sets the default values from the image
slide.width = imgWidth;
slide.height = imgHeight;
if (maxWidth > 0) {
slide.width = maxWidth;
slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);
}
if (maxHeight > 0) {
slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);
slide.height = maxHeight;
}
},
// Create iframe wrapper, iframe and bindings
// ==========================================
setIframe: function (slide) {
var self = this,
opts = slide.opts.iframe,
$slide = slide.$slide,
$iframe;
slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>')
.css(opts.css)
.appendTo($slide);
$slide.addClass("fancybox-slide--" + slide.contentType);
slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime()))
.attr(opts.attr)
.appendTo(slide.$content);
if (opts.preload) {
self.showLoading(slide);
// Unfortunately, it is not always possible to determine if iframe is successfully loaded
// (due to browser security policy)
$iframe.on("load.fb error.fb", function (e) {
this.isReady = 1;
slide.$slide.trigger("refresh");
self.afterLoad(slide);
});
// Recalculate iframe content size
// ===============================
$slide.on("refresh.fb", function () {
var $content = slide.$content,
frameWidth = opts.css.width,
frameHeight = opts.css.height,
$contents,
$body;
if ($iframe[0].isReady !== 1) {
return;
}
try {
$contents = $iframe.contents();
$body = $contents.find("body");
} catch (ignore) {}
// Calculate content dimensions, if it is accessible
if ($body && $body.length && $body.children().length) {
// Avoid scrolling to top (if multiple instances)
$slide.css("overflow", "visible");
$content.css({
width: "100%",
"max-width": "100%",
height: "9999px"
});
if (frameWidth === undefined) {
frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));
}
$content.css("width", frameWidth ? frameWidth : "").css("max-width", "");
if (frameHeight === undefined) {
frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));
}
$content.css("height", frameHeight ? frameHeight : "");
$slide.css("overflow", "auto");
}
$content.removeClass("fancybox-is-hidden");
});
} else {
self.afterLoad(slide);
}
$iframe.attr("src", slide.src);
// Remove iframe if closing or changing gallery item
$slide.one("onReset", function () {
// This helps IE not to throw errors when closing
try {
$(this)
.find("iframe")
.hide()
.unbind()
.attr("src", "//about:blank");
} catch (ignore) {}
$(this)
.off("refresh.fb")
.empty();
slide.isLoaded = false;
slide.isRevealed = false;
});
},
// Wrap and append content to the slide
// ======================================
setContent: function (slide, content) {
var self = this;
if (self.isClosing) {
return;
}
self.hideLoading(slide);
if (slide.$content) {
$.fancybox.stop(slide.$content);
}
slide.$slide.empty();
// If content is a jQuery object, then it will be moved to the slide.
// The placeholder is created so we will know where to put it back.
if (isQuery(content) && content.parent().length) {
// Make sure content is not already moved to fancyBox
if (content.hasClass("fancybox-content") || content.parent().hasClass("fancybox-content")) {
content.parents(".fancybox-slide").trigger("onReset");
}
// Create temporary element marking original place of the content
slide.$placeholder = $("<div>")
.hide()
.insertAfter(content);
// Make sure content is visible
content.css("display", "inline-block");
} else if (!slide.hasError) {
// If content is just a plain text, try to convert it to html
if ($.type(content) === "string") {
content = $("<div>")
.append($.trim(content))
.contents();
}
// If "filter" option is provided, then filter content
if (slide.opts.filter) {
content = $("<div>")
.html(content)
.find(slide.opts.filter);
}
}
slide.$slide.one("onReset", function () {
// Pause all html5 video/audio
$(this)
.find("video,audio")
.trigger("pause");
// Put content back
if (slide.$placeholder) {
slide.$placeholder.after(content.removeClass("fancybox-content").hide()).remove();
slide.$placeholder = null;
}
// Remove custom close button
if (slide.$smallBtn) {
slide.$smallBtn.remove();
slide.$smallBtn = null;
}
// Remove content and mark slide as not loaded
if (!slide.hasError) {
$(this).empty();
slide.isLoaded = false;
slide.isRevealed = false;
}
});
$(content).appendTo(slide.$slide);
if ($(content).is("video,audio")) {
$(content).addClass("fancybox-video");
$(content).wrap("<div></div>");
slide.contentType = "video";
slide.opts.width = slide.opts.width || $(content).attr("width");
slide.opts.height = slide.opts.height || $(content).attr("height");
}
slide.$content = slide.$slide
.children()
.filter("div,form,main,video,audio,article,.fancybox-content")
.first();
slide.$content.siblings().hide();
// Re-check if there is a valid content
// (in some cases, ajax response can contain various elements or plain text)
if (!slide.$content.length) {
slide.$content = slide.$slide
.wrapInner("<div></div>")
.children()
.first();
}
slide.$content.addClass("fancybox-content");
slide.$slide.addClass("fancybox-slide--" + slide.contentType);
self.afterLoad(slide);
},
// Display error message
// =====================
setError: function (slide) {
slide.hasError = true;
slide.$slide
.trigger("onReset")
.removeClass("fancybox-slide--" + slide.contentType)
.addClass("fancybox-slide--error");
slide.contentType = "html";
this.setContent(slide, this.translate(slide, slide.opts.errorTpl));
if (slide.pos === this.currPos) {
this.isAnimating = false;
}
},
// Show loading icon inside the slide
// ==================================
showLoading: function (slide) {
var self = this;
slide = slide || self.current;
if (slide && !slide.$spinner) {
slide.$spinner = $(self.translate(self, self.opts.spinnerTpl))
.appendTo(slide.$slide)
.hide()
.fadeIn("fast");
}
},
// Remove loading icon from the slide
// ==================================
hideLoading: function (slide) {
var self = this;
slide = slide || self.current;
if (slide && slide.$spinner) {
slide.$spinner.stop().remove();
delete slide.$spinner;
}
},
// Adjustments after slide content has been loaded
// ===============================================
afterLoad: function (slide) {
var self = this;
if (self.isClosing) {
return;
}
slide.isLoading = false;
slide.isLoaded = true;
self.trigger("afterLoad", slide);
self.hideLoading(slide);
// Add small close button
if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {
slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);
}
// Disable right click
if (slide.opts.protect && slide.$content && !slide.hasError) {
slide.$content.on("contextmenu.fb", function (e) {
if (e.button == 2) {
e.preventDefault();
}
return true;
});
// Add fake element on top of the image
// This makes a bit harder for user to select image
if (slide.type === "image") {
$('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);
}
}
self.adjustCaption(slide);
self.adjustLayout(slide);
if (slide.pos === self.currPos) {
self.updateCursor();
}
self.revealContent(slide);
},
// Prevent caption overlap,
// fix css inconsistency across browsers
// =====================================
adjustCaption: function (slide) {
var self = this,
current = slide || self.current,
caption = current.opts.caption,
preventOverlap = current.opts.preventCaptionOverlap,
$caption = self.$refs.caption,
$clone,
captionH = false;
$caption.toggleClass("fancybox-caption--separate", preventOverlap);
if (preventOverlap && caption && caption.length) {
if (current.pos !== self.currPos) {
$clone = $caption.clone().appendTo($caption.parent());
$clone
.children()
.eq(0)
.empty()
.html(caption);
captionH = $clone.outerHeight(true);
$clone.empty().remove();
} else if (self.$caption) {
captionH = self.$caption.outerHeight(true);
}
current.$slide.css("padding-bottom", captionH || "");
}
},
// Simple hack to fix inconsistency across browsers, described here (affects Edge, too):
// https://bugzilla.mozilla.org/show_bug.cgi?id=748518
// ====================================================================================
adjustLayout: function (slide) {
var self = this,
current = slide || self.current,
scrollHeight,
marginBottom,
inlinePadding,
actualPadding;
if (current.isLoaded && current.opts.disableLayoutFix !== true) {
current.$content.css("margin-bottom", "");
// If we would always set margin-bottom for the content,
// then it would potentially break vertical align
if (current.$content.outerHeight() > current.$slide.height() + 0.5) {
inlinePadding = current.$slide[0].style["padding-bottom"];
actualPadding = current.$slide.css("padding-bottom");
if (parseFloat(actualPadding) > 0) {
scrollHeight = current.$slide[0].scrollHeight;
current.$slide.css("padding-bottom", 0);
if (Math.abs(scrollHeight - current.$slide[0].scrollHeight) < 1) {
marginBottom = actualPadding;
}
current.$slide.css("padding-bottom", inlinePadding);
}
}
current.$content.css("margin-bottom", marginBottom);
}
},
// Make content visible
// This method is called right after content has been loaded or
// user navigates gallery and transition should start
// ============================================================
revealContent: function (slide) {
var self = this,
$slide = slide.$slide,
end = false,
start = false,
isMoved = self.isMoved(slide),
isRevealed = slide.isRevealed,
effect,
effectClassName,
duration,
opacity;
slide.isRevealed = true;
effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"];
duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"];
duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);
if (isMoved || slide.pos !== self.currPos || !duration) {
effect = false;
}
// Check if can zoom
if (effect === "zoom") {
if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) {
end = self.getFitPos(slide);
} else {
effect = "fade";
}
}
// Zoom animation
// ==============
if (effect === "zoom") {
self.isAnimating = true;
end.scaleX = end.width / start.width;
end.scaleY = end.height / start.height;
// Check if we need to animate opacity
opacity = slide.opts.zoomOpacity;
if (opacity == "auto") {
opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;
}
if (opacity) {
start.opacity = 0.1;
end.opacity = 1;
}
// Draw image at start position
$.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start);
forceRedraw(slide.$content);
// Start animation
$.fancybox.animate(slide.$content, end, duration, function () {
self.isAnimating = false;
self.complete();
});
return;
}
self.updateSlide(slide);
// Simply show content if no effect
// ================================
if (!effect) {
slide.$content.removeClass("fancybox-is-hidden");
if (!isRevealed && isMoved && slide.type === "image" && !slide.hasError) {
slide.$content.hide().fadeIn("fast");
}
if (slide.pos === self.currPos) {
self.complete();
}
return;
}
// Prepare for CSS transiton
// =========================
$.fancybox.stop($slide);
//effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect;
effectClassName = "fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-animated fancybox-fx-" + effect;
$slide.addClass(effectClassName).removeClass("fancybox-slide--current"); //.addClass(effectClassName);
slide.$content.removeClass("fancybox-is-hidden");
// Force reflow
forceRedraw($slide);
if (slide.type !== "image") {
slide.$content.hide().show(0);
}
$.fancybox.animate(
$slide,
"fancybox-slide--current",
duration,
function () {
$slide.removeClass(effectClassName).css({
transform: "",
opacity: ""
});
if (slide.pos === self.currPos) {
self.complete();
}
},
true
);
},
// Check if we can and have to zoom from thumbnail
//================================================
getThumbPos: function (slide) {
var rez = false,
$thumb = slide.$thumb,
thumbPos,
btw,
brw,
bbw,
blw;
if (!$thumb || !inViewport($thumb[0])) {
return false;
}
thumbPos = $.fancybox.getTranslate($thumb);
btw = parseFloat($thumb.css("border-top-width") || 0);
brw = parseFloat($thumb.css("border-right-width") || 0);
bbw = parseFloat($thumb.css("border-bottom-width") || 0);
blw = parseFloat($thumb.css("border-left-width") || 0);
rez = {
top: thumbPos.top + btw,
left: thumbPos.left + blw,
width: thumbPos.width - brw - blw,
height: thumbPos.height - btw - bbw,
scaleX: 1,
scaleY: 1
};
return thumbPos.width > 0 && thumbPos.height > 0 ? rez : false;
},
// Final adjustments after current gallery item is moved to position
// and it`s content is loaded
// ==================================================================
complete: function () {
var self = this,
current = self.current,
slides = {},
$el;
if (self.isMoved() || !current.isLoaded) {
return;
}
if (!current.isComplete) {
current.isComplete = true;
current.$slide.siblings().trigger("onReset");
self.preload("inline");
// Trigger any CSS transiton inside the slide
forceRedraw(current.$slide);
current.$slide.addClass("fancybox-slide--complete");
// Remove unnecessary slides
$.each(self.slides, function (key, slide) {
if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {
slides[slide.pos] = slide;
} else if (slide) {
$.fancybox.stop(slide.$slide);
slide.$slide.off().remove();
}
});
self.slides = slides;
}
self.isAnimating = false;
self.updateCursor();
self.trigger("afterShow");
// Autoplay first html5 video/audio
if (!!current.opts.video.autoStart) {
current.$slide
.find("video,audio")
.filter(":visible:first")
.trigger("play")
.one("ended", function () {
if (Document.exitFullscreen) {
Document.exitFullscreen();
} else if (this.webkitExitFullscreen) {
this.webkitExitFullscreen();
}
self.next();
});
}
// Try to focus on the first focusable element
if (current.opts.autoFocus && current.contentType === "html") {
// Look for the first input with autofocus attribute
$el = current.$content.find("input[autofocus]:enabled:visible:first");
if ($el.length) {
$el.trigger("focus");
} else {
self.focus(null, true);
}
}
// Avoid jumping
current.$slide.scrollTop(0).scrollLeft(0);
},
// Preload next and previous slides
// ================================
preload: function (type) {
var self = this,
prev,
next;
if (self.group.length < 2) {
return;
}
next = self.slides[self.currPos + 1];
prev = self.slides[self.currPos - 1];
if (prev && prev.type === type) {
self.loadSlide(prev);
}
if (next && next.type === type) {
self.loadSlide(next);
}
},
// Try to find and focus on the first focusable element
// ====================================================
focus: function (e, firstRun) {
var self = this,
focusableStr = [
"a[href]",
"area[href]",
'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
"select:not([disabled]):not([aria-hidden])",
"textarea:not([disabled]):not([aria-hidden])",
"button:not([disabled]):not([aria-hidden])",
"iframe",
"object",
"embed",
"video",
"audio",
"[contenteditable]",
'[tabindex]:not([tabindex^="-"])'
].join(","),
focusableItems,
focusedItemIndex;
if (self.isClosing) {
return;
}
if (e || !self.current || !self.current.isComplete) {
// Focus on any element inside fancybox
focusableItems = self.$refs.container.find("*:visible");
} else {
// Focus inside current slide
focusableItems = self.current.$slide.find("*:visible" + (firstRun ? ":not(.fancybox-close-small)" : ""));
}
focusableItems = focusableItems.filter(focusableStr).filter(function () {
return $(this).css("visibility") !== "hidden" && !$(this).hasClass("disabled");
});
if (focusableItems.length) {
focusedItemIndex = focusableItems.index(document.activeElement);
if (e && e.shiftKey) {
// Back tab
if (focusedItemIndex < 0 || focusedItemIndex == 0) {
e.preventDefault();
focusableItems.eq(focusableItems.length - 1).trigger("focus");
}
} else {
// Outside or Forward tab
if (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {
if (e) {
e.preventDefault();
}
focusableItems.eq(0).trigger("focus");
}
}
} else {
self.$refs.container.trigger("focus");
}
},
// Activates current instance - brings container to the front and enables keyboard,
// notifies other instances about deactivating
// =================================================================================
activate: function () {
var self = this;
// Deactivate all instances
$(".fancybox-container").each(function () {
var instance = $(this).data("FancyBox");
// Skip self and closing instances
if (instance && instance.id !== self.id && !instance.isClosing) {
instance.trigger("onDeactivate");
instance.removeEvents();
instance.isVisible = false;
}
});
self.isVisible = true;
if (self.current || self.isIdle) {
self.update();
self.updateControls();
}
self.trigger("onActivate");
self.addEvents();
},
// Start closing procedure
// This will start "zoom-out" animation if needed and clean everything up afterwards
// =================================================================================
close: function (e, d) {
var self = this,
current = self.current,
effect,
duration,
$content,
domRect,
opacity,
start,
end;
var done = function () {
self.cleanUp(e);
};
if (self.isClosing) {
return false;
}
self.isClosing = true;
// If beforeClose callback prevents closing, make sure content is centered
if (self.trigger("beforeClose", e) === false) {
self.isClosing = false;
requestAFrame(function () {
self.update();
});
return false;
}
// Remove all events
// If there are multiple instances, they will be set again by "activate" method
self.removeEvents();
$content = current.$content;
effect = current.opts.animationEffect;
duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;
current.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated");
if (e !== true) {
$.fancybox.stop(current.$slide);
} else {
effect = false;
}
// Remove other slides
current.$slide
.siblings()
.trigger("onReset")
.remove();
// Trigger animations
if (duration) {
self.$refs.container
.removeClass("fancybox-is-open")
.addClass("fancybox-is-closing")
.css("transition-duration", duration + "ms");
}
// Clean up
self.hideLoading(current);
self.hideControls(true);
self.updateCursor();
// Check if possible to zoom-out
if (
effect === "zoom" &&
!($content && duration && current.type === "image" && !self.isMoved() && !current.hasError && (end = self.getThumbPos(current)))
) {
effect = "fade";
}
if (effect === "zoom") {
$.fancybox.stop($content);
domRect = $.fancybox.getTranslate($content);
start = {
top: domRect.top,
left: domRect.left,
scaleX: domRect.width / end.width,
scaleY: domRect.height / end.height,
width: end.width,
height: end.height
};
// Check if we need to animate opacity
opacity = current.opts.zoomOpacity;
if (opacity == "auto") {
opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;
}
if (opacity) {
end.opacity = 0;
}
$.fancybox.setTranslate($content, start);
forceRedraw($content);
$.fancybox.animate($content, end, duration, done);
return true;
}
if (effect && duration) {
$.fancybox.animate(
current.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),
"fancybox-animated fancybox-fx-" + effect,
duration,
done
);
} else {
// If skip animation
if (e === true) {
setTimeout(done, duration);
} else {
done();
}
}
return true;
},
// Final adjustments after removing the instance
// =============================================
cleanUp: function (e) {
var self = this,
instance,
$focus = self.current.opts.$orig,
x,
y;
self.current.$slide.trigger("onReset");
self.$refs.container.empty().remove();
self.trigger("afterClose", e);
// Place back focus
if (!!self.current.opts.backFocus) {
if (!$focus || !$focus.length || !$focus.is(":visible")) {
$focus = self.$trigger;
}
if ($focus && $focus.length) {
x = window.scrollX;
y = window.scrollY;
$focus.trigger("focus");
$("html, body")
.scrollTop(y)
.scrollLeft(x);
}
}
self.current = null;
// Check if there are other instances
instance = $.fancybox.getInstance();
if (instance) {
instance.activate();
} else {
$("body").removeClass("fancybox-active compensate-for-scrollbar");
$("#fancybox-style-noscroll").remove();
}
},
// Call callback and trigger an event
// ==================================
trigger: function (name, slide) {
var args = Array.prototype.slice.call(arguments, 1),
self = this,
obj = slide && slide.opts ? slide : self.current,
rez;
if (obj) {
args.unshift(obj);
} else {
obj = self;
}
args.unshift(self);
if ($.isFunction(obj.opts[name])) {
rez = obj.opts[name].apply(obj, args);
}
if (rez === false) {
return rez;
}
if (name === "afterClose" || !self.$refs) {
$D.trigger(name + ".fb", args);
} else {
self.$refs.container.trigger(name + ".fb", args);
}
},
// Update infobar values, navigation button states and reveal caption
// ==================================================================
updateControls: function () {
var self = this,
current = self.current,
index = current.index,
$container = self.$refs.container,
$caption = self.$refs.caption,
caption = current.opts.caption;
// Recalculate content dimensions
current.$slide.trigger("refresh");
// Set caption
if (caption && caption.length) {
self.$caption = $caption;
$caption
.children()
.eq(0)
.html(caption);
} else {
self.$caption = null;
}
if (!self.hasHiddenControls && !self.isIdle) {
self.showControls();
}
// Update info and navigation elements
$container.find("[data-fancybox-count]").html(self.group.length);
$container.find("[data-fancybox-index]").html(index + 1);
$container.find("[data-fancybox-prev]").prop("disabled", !current.opts.loop && index <= 0);
$container.find("[data-fancybox-next]").prop("disabled", !current.opts.loop && index >= self.group.length - 1);
if (current.type === "image") {
// Re-enable buttons; update download button source
$container
.find("[data-fancybox-zoom]")
.show()
.end()
.find("[data-fancybox-download]")
.attr("href", current.opts.image.src || current.src)
.show();
} else if (current.opts.toolbar) {
$container.find("[data-fancybox-download],[data-fancybox-zoom]").hide();
}
// Make sure focus is not on disabled button/element
if ($(document.activeElement).is(":hidden,[disabled]")) {
self.$refs.container.trigger("focus");
}
},
// Hide toolbar and caption
// ========================
hideControls: function (andCaption) {
var self = this,
arr = ["infobar", "toolbar", "nav"];
if (andCaption || !self.current.opts.preventCaptionOverlap) {
arr.push("caption");
}
this.$refs.container.removeClass(
arr
.map(function (i) {
return "fancybox-show-" + i;
})
.join(" ")
);
this.hasHiddenControls = true;
},
showControls: function () {
var self = this,
opts = self.current ? self.current.opts : self.opts,
$container = self.$refs.container;
self.hasHiddenControls = false;
self.idleSecondsCounter = 0;
$container
.toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons))
.toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1))
.toggleClass("fancybox-show-caption", !!self.$caption)
.toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1))
.toggleClass("fancybox-is-modal", !!opts.modal);
},
// Toggle toolbar and caption
// ==========================
toggleControls: function () {
if (this.hasHiddenControls) {
this.showControls();
} else {
this.hideControls();
}
}
});
$.fancybox = {
version: "3.5.7",
defaults: defaults,
// Get current instance and execute a command.
//
// Examples of usage:
//
// $instance = $.fancybox.getInstance();
// $.fancybox.getInstance().jumpTo( 1 );
// $.fancybox.getInstance( 'jumpTo', 1 );
// $.fancybox.getInstance( function() {
// console.info( this.currIndex );
// });
// ======================================================
getInstance: function (command) {
var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),
args = Array.prototype.slice.call(arguments, 1);
if (instance instanceof FancyBox) {
if ($.type(command) === "string") {
instance[command].apply(instance, args);
} else if ($.type(command) === "function") {
command.apply(instance, args);
}
return instance;
}
return false;
},
// Create new instance
// ===================
open: function (items, opts, index) {
return new FancyBox(items, opts, index);
},
// Close current or all instances
// ==============================
close: function (all) {
var instance = this.getInstance();
if (instance) {
instance.close();
// Try to find and close next instance
if (all === true) {
this.close(all);
}
}
},
// Close all instances and unbind all events
// =========================================
destroy: function () {
this.close(true);
$D.add("body").off("click.fb-start", "**");
},
// Try to detect mobile devices
// ============================
isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
// Detect if 'translate3d' support is available
// ============================================
use3d: (function () {
var div = document.createElement("div");
return (
window.getComputedStyle &&
window.getComputedStyle(div) &&
window.getComputedStyle(div).getPropertyValue("transform") &&
!(document.documentMode && document.documentMode < 11)
);
})(),
// Helper function to get current visual state of an element
// returns array[ top, left, horizontal-scale, vertical-scale, opacity ]
// =====================================================================
getTranslate: function ($el) {
var domRect;
if (!$el || !$el.length) {
return false;
}
domRect = $el[0].getBoundingClientRect();
return {
top: domRect.top || 0,
left: domRect.left || 0,
width: domRect.width,
height: domRect.height,
opacity: parseFloat($el.css("opacity"))
};
},
// Shortcut for setting "translate3d" properties for element
// Can set be used to set opacity, too
// ========================================================
setTranslate: function ($el, props) {
var str = "",
css = {};
if (!$el || !props) {
return;
}
if (props.left !== undefined || props.top !== undefined) {
str =
(props.left === undefined ? $el.position().left : props.left) +
"px, " +
(props.top === undefined ? $el.position().top : props.top) +
"px";
if (this.use3d) {
str = "translate3d(" + str + ", 0px)";
} else {
str = "translate(" + str + ")";
}
}
if (props.scaleX !== undefined && props.scaleY !== undefined) {
str += " scale(" + props.scaleX + ", " + props.scaleY + ")";
} else if (props.scaleX !== undefined) {
str += " scaleX(" + props.scaleX + ")";
}
if (str.length) {
css.transform = str;
}
if (props.opacity !== undefined) {
css.opacity = props.opacity;
}
if (props.width !== undefined) {
css.width = props.width;
}
if (props.height !== undefined) {
css.height = props.height;
}
return $el.css(css);
},
// Simple CSS transition handler
// =============================
animate: function ($el, to, duration, callback, leaveAnimationName) {
var self = this,
from;
if ($.isFunction(duration)) {
callback = duration;
duration = null;
}
self.stop($el);
from = self.getTranslate($el);
$el.on(transitionEnd, function (e) {
// Skip events from child elements and z-index change
if (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) {
return;
}
self.stop($el);
if ($.isNumeric(duration)) {
$el.css("transition-duration", "");
}
if ($.isPlainObject(to)) {
if (to.scaleX !== undefined && to.scaleY !== undefined) {
self.setTranslate($el, {
top: to.top,
left: to.left,
width: from.width * to.scaleX,
height: from.height * to.scaleY,
scaleX: 1,
scaleY: 1
});
}
} else if (leaveAnimationName !== true) {
$el.removeClass(to);
}
if ($.isFunction(callback)) {
callback(e);
}
});
if ($.isNumeric(duration)) {
$el.css("transition-duration", duration + "ms");
}
// Start animation by changing CSS properties or class name
if ($.isPlainObject(to)) {
if (to.scaleX !== undefined && to.scaleY !== undefined) {
delete to.width;
delete to.height;
if ($el.parent().hasClass("fancybox-slide--image")) {
$el.parent().addClass("fancybox-is-scaling");
}
}
$.fancybox.setTranslate($el, to);
} else {
$el.addClass(to);
}
// Make sure that `transitionend` callback gets fired
$el.data(
"timer",
setTimeout(function () {
$el.trigger(transitionEnd);
}, duration + 33)
);
},
stop: function ($el, callCallback) {
if ($el && $el.length) {
clearTimeout($el.data("timer"));
if (callCallback) {
$el.trigger(transitionEnd);
}
$el.off(transitionEnd).css("transition-duration", "");
$el.parent().removeClass("fancybox-is-scaling");
}
}
};
// Default click handler for "fancyboxed" links
// ============================================
function _run(e, opts) {
var items = [],
index = 0,
$target,
value,
instance;
// Avoid opening multiple times
if (e && e.isDefaultPrevented()) {
return;
}
e.preventDefault();
opts = opts || {};
if (e && e.data) {
opts = mergeOpts(e.data.options, opts);
}
$target = opts.$target || $(e.currentTarget).trigger("blur");
instance = $.fancybox.getInstance();
if (instance && instance.$trigger && instance.$trigger.is($target)) {
return;
}
if (opts.selector) {
items = $(opts.selector);
} else {
// Get all related items and find index for clicked one
value = $target.attr("data-fancybox") || "";
if (value) {
items = e.data ? e.data.items : [];
items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');
} else {
items = [$target];
}
}
index = $(items).index($target);
// Sometimes current item can not be found
if (index < 0) {
index = 0;
}
instance = $.fancybox.open(items, opts, index);
// Save last active element
instance.$trigger = $target;
}
// Create a jQuery plugin
// ======================
$.fn.fancybox = function (options) {
var selector;
options = options || {};
selector = options.selector || false;
if (selector) {
// Use body element instead of document so it executes first
$("body")
.off("click.fb-start", selector)
.on("click.fb-start", selector, {
options: options
}, _run);
} else {
this.off("click.fb-start").on(
"click.fb-start", {
items: this,
options: options
},
_run
);
}
return this;
};
// Self initializing plugin for all elements having `data-fancybox` attribute
// ==========================================================================
$D.on("click.fb-start", "[data-fancybox]", _run);
// Enable "trigger elements"
// =========================
$D.on("click.fb-start", "[data-fancybox-trigger]", function (e) {
$('[data-fancybox="' + $(this).attr("data-fancybox-trigger") + '"]')
.eq($(this).attr("data-fancybox-index") || 0)
.trigger("click.fb-start", {
$trigger: $(this)
});
});
// Track focus event for better accessibility styling
// ==================================================
(function () {
var buttonStr = ".fancybox-button",
focusStr = "fancybox-focus",
$pressed = null;
$D.on("mousedown mouseup focus blur", buttonStr, function (e) {
switch (e.type) {
case "mousedown":
$pressed = $(this);
break;
case "mouseup":
$pressed = null;
break;
case "focusin":
$(buttonStr).removeClass(focusStr);
if (!$(this).is($pressed) && !$(this).is("[disabled]")) {
$(this).addClass(focusStr);
}
break;
case "focusout":
$(buttonStr).removeClass(focusStr);
break;
}
});
})();
})(window, document, jQuery);
// ==========================================================================
//
// Media
// Adds additional media type support
//
// ==========================================================================
(function ($) {
"use strict";
// Object containing properties for each media type
var defaults = {
youtube: {
matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,
params: {
autoplay: 1,
autohide: 1,
fs: 1,
rel: 0,
hd: 1,
wmode: "transparent",
enablejsapi: 1,
html5: 1
},
paramPlace: 8,
type: "iframe",
url: "https://www.youtube-nocookie.com/embed/$4",
thumb: "https://img.youtube.com/vi/$4/hqdefault.jpg"
},
vimeo: {
matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,
params: {
autoplay: 1,
hd: 1,
show_title: 1,
show_byline: 1,
show_portrait: 0,
fullscreen: 1
},
paramPlace: 3,
type: "iframe",
url: "//player.vimeo.com/video/$2"
},
instagram: {
matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
type: "image",
url: "//$1/p/$2/media/?size=l"
},
// Examples:
// http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
// https://www.google.com/maps/@37.7852006,-122.4146355,14.65z
// https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en
// https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572
gmap_place: {
matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,
type: "iframe",
url: function (rez) {
return (
"//maps.google." +
rez[2] +
"/?ll=" +
(rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") +
"&output=" +
(rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed")
);
}
},
// Examples:
// https://www.google.com/maps/search/Empire+State+Building/
// https://www.google.com/maps/search/?api=1&query=centurylink+field
// https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393
gmap_search: {
matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,
type: "iframe",
url: function (rez) {
return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed";
}
}
};
// Formats matching url to final form
var format = function (url, rez, params) {
if (!url) {
return;
}
params = params || "";
if ($.type(params) === "object") {
params = $.param(params, true);
}
$.each(rez, function (key, value) {
url = url.replace("$" + key, value || "");
});
if (params.length) {
url += (url.indexOf("?") > 0 ? "&" : "?") + params;
}
return url;
};
$(document).on("objectNeedsType.fb", function (e, instance, item) {
var url = item.src || "",
type = false,
media,
thumb,
rez,
params,
urlParams,
paramObj,
provider;
media = $.extend(true, {}, defaults, item.opts.media);
// Look for any matching media type
$.each(media, function (providerName, providerOpts) {
rez = url.match(providerOpts.matcher);
if (!rez) {
return;
}
type = providerOpts.type;
provider = providerName;
paramObj = {};
if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {
urlParams = rez[providerOpts.paramPlace];
if (urlParams[0] == "?") {
urlParams = urlParams.substring(1);
}
urlParams = urlParams.split("&");
for (var m = 0; m < urlParams.length; ++m) {
var p = urlParams[m].split("=", 2);
if (p.length == 2) {
paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
}
}
params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);
url =
$.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);
thumb =
$.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);
if (providerName === "youtube") {
url = url.replace(/&t=((\d+)m)?(\d+)s/, function (match, p1, m, s) {
return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));
});
} else if (providerName === "vimeo") {
url = url.replace("&%23", "#");
}
return false;
});
// If it is found, then change content type and update the url
if (type) {
if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {
item.opts.thumb = thumb;
}
if (type === "iframe") {
item.opts = $.extend(true, item.opts, {
iframe: {
preload: false,
attr: {
scrolling: "no"
}
}
});
}
$.extend(item, {
type: type,
src: url,
origSrc: item.src,
contentSource: provider,
contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video"
});
} else if (url) {
item.type = item.opts.defaultType;
}
});
// Load YouTube/Video API on request to detect when video finished playing
var VideoAPILoader = {
youtube: {
src: "https://www.youtube.com/iframe_api",
class: "YT",
loading: false,
loaded: false
},
vimeo: {
src: "https://player.vimeo.com/api/player.js",
class: "Vimeo",
loading: false,
loaded: false
},
load: function (vendor) {
var _this = this,
script;
if (this[vendor].loaded) {
setTimeout(function () {
_this.done(vendor);
});
return;
}
if (this[vendor].loading) {
return;
}
this[vendor].loading = true;
script = document.createElement("script");
script.type = "text/javascript";
script.src = this[vendor].src;
if (vendor === "youtube") {
window.onYouTubeIframeAPIReady = function () {
_this[vendor].loaded = true;
_this.done(vendor);
};
} else {
script.onload = function () {
_this[vendor].loaded = true;
_this.done(vendor);
};
}
document.body.appendChild(script);
},
done: function (vendor) {
var instance, $el, player;
if (vendor === "youtube") {
delete window.onYouTubeIframeAPIReady;
}
instance = $.fancybox.getInstance();
if (instance) {
$el = instance.current.$content.find("iframe");
if (vendor === "youtube" && YT !== undefined && YT) {
player = new YT.Player($el.attr("id"), {
events: {
onStateChange: function (e) {
if (e.data == 0) {
instance.next();
}
}
}
});
} else if (vendor === "vimeo" && Vimeo !== undefined && Vimeo) {
player = new Vimeo.Player($el);
player.on("ended", function () {
instance.next();
});
}
}
}
};
$(document).on({
"afterShow.fb": function (e, instance, current) {
if (instance.group.length > 1 && (current.contentSource === "youtube" || current.contentSource === "vimeo")) {
VideoAPILoader.load(current.contentSource);
}
}
});
})(jQuery);
// ==========================================================================
//
// Guestures
// Adds touch guestures, handles click and tap events
//
// ==========================================================================
(function (window, document, $) {
"use strict";
var requestAFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
// if all else fails, use setTimeout
function (callback) {
return window.setTimeout(callback, 1000 / 60);
}
);
})();
var cancelAFrame = (function () {
return (
window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
function (id) {
window.clearTimeout(id);
}
);
})();
var getPointerXY = function (e) {
var result = [];
e = e.originalEvent || e || window.e;
e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];
for (var key in e) {
if (e[key].pageX) {
result.push({
x: e[key].pageX,
y: e[key].pageY
});
} else if (e[key].clientX) {
result.push({
x: e[key].clientX,
y: e[key].clientY
});
}
}
return result;
};
var distance = function (point2, point1, what) {
if (!point1 || !point2) {
return 0;
}
if (what === "x") {
return point2.x - point1.x;
} else if (what === "y") {
return point2.y - point1.y;
}
return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
};
var isClickable = function ($el) {
if (
$el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe') ||
$.isFunction($el.get(0).onclick) ||
$el.data("selectable")
) {
return true;
}
// Check for attributes like data-fancybox-next or data-fancybox-close
for (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {
if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") {
return true;
}
}
return false;
};
var hasScrollbars = function (el) {
var overflowY = window.getComputedStyle(el)["overflow-y"],
overflowX = window.getComputedStyle(el)["overflow-x"],
vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight,
horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth;
return vertical || horizontal;
};
var isScrollable = function ($el) {
var rez = false;
while (true) {
rez = hasScrollbars($el.get(0));
if (rez) {
break;
}
$el = $el.parent();
if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) {
break;
}
}
return rez;
};
var Guestures = function (instance) {
var self = this;
self.instance = instance;
self.$bg = instance.$refs.bg;
self.$stage = instance.$refs.stage;
self.$container = instance.$refs.container;
self.destroy();
self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart"));
};
Guestures.prototype.destroy = function () {
var self = this;
self.$container.off(".fb.touch");
$(document).off(".fb.touch");
if (self.requestId) {
cancelAFrame(self.requestId);
self.requestId = null;
}
if (self.tapped) {
clearTimeout(self.tapped);
self.tapped = null;
}
};
Guestures.prototype.ontouchstart = function (e) {
var self = this,
$target = $(e.target),
instance = self.instance,
current = instance.current,
$slide = current.$slide,
$content = current.$content,
isTouchDevice = e.type == "touchstart";
// Do not respond to both (touch and mouse) events
if (isTouchDevice) {
self.$container.off("mousedown.fb.touch");
}
// Ignore right click
if (e.originalEvent && e.originalEvent.button == 2) {
return;
}
// Ignore taping on links, buttons, input elements
if (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {
return;
}
// Ignore clicks on the scrollbar
if (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {
return;
}
// Ignore clicks while zooming or closing
if (!current || instance.isAnimating || current.$slide.hasClass("fancybox-animated")) {
e.stopPropagation();
e.preventDefault();
return;
}
self.realPoints = self.startPoints = getPointerXY(e);
if (!self.startPoints.length) {
return;
}
// Allow other scripts to catch touch event if "touch" is set to false
if (current.touch) {
e.stopPropagation();
}
self.startEvent = e;
self.canTap = true;
self.$target = $target;
self.$content = $content;
self.opts = current.opts.touch;
self.isPanning = false;
self.isSwiping = false;
self.isZooming = false;
self.isScrolling = false;
self.canPan = instance.canPan();
self.startTime = new Date().getTime();
self.distanceX = self.distanceY = self.distance = 0;
self.canvasWidth = Math.round($slide[0].clientWidth);
self.canvasHeight = Math.round($slide[0].clientHeight);
self.contentLastPos = null;
self.contentStartPos = $.fancybox.getTranslate(self.$content) || {
top: 0,
left: 0
};
self.sliderStartPos = $.fancybox.getTranslate($slide);
// Since position will be absolute, but we need to make it relative to the stage
self.stagePos = $.fancybox.getTranslate(instance.$refs.stage);
self.sliderStartPos.top -= self.stagePos.top;
self.sliderStartPos.left -= self.stagePos.left;
self.contentStartPos.top -= self.stagePos.top;
self.contentStartPos.left -= self.stagePos.left;
$(document)
.off(".fb.touch")
.on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend"))
.on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove"));
if ($.fancybox.isMobile) {
document.addEventListener("scroll", self.onscroll, true);
}
// Skip if clicked outside the sliding area
if (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {
if ($target.is(".fancybox-image")) {
e.preventDefault();
}
if (!($.fancybox.isMobile && $target.parents(".fancybox-caption").length)) {
return;
}
}
self.isScrollable = isScrollable($target) || isScrollable($target.parent());
// Check if element is scrollable and try to prevent default behavior (scrolling)
if (!($.fancybox.isMobile && self.isScrollable)) {
e.preventDefault();
}
// One finger or mouse click - swipe or pan an image
if (self.startPoints.length === 1 || current.hasError) {
if (self.canPan) {
$.fancybox.stop(self.$content);
self.isPanning = true;
} else {
self.isSwiping = true;
}
self.$container.addClass("fancybox-is-grabbing");
}
// Two fingers - zoom image
if (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) {
self.canTap = false;
self.isSwiping = false;
self.isPanning = false;
self.isZooming = true;
$.fancybox.stop(self.$content);
self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();
self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();
self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;
self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;
self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);
}
};
Guestures.prototype.onscroll = function (e) {
var self = this;
self.isScrolling = true;
document.removeEventListener("scroll", self.onscroll, true);
};
Guestures.prototype.ontouchmove = function (e) {
var self = this;
// Make sure user has not released over iframe or disabled element
if (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {
self.ontouchend(e);
return;
}
if (self.isScrolling) {
self.canTap = false;
return;
}
self.newPoints = getPointerXY(e);
if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {
return;
}
if (!(self.isSwiping && self.isSwiping === true)) {
e.preventDefault();
}
self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x");
self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y");
self.distance = distance(self.newPoints[0], self.startPoints[0]);
// Skip false ontouchmove events (Chrome)
if (self.distance > 0) {
if (self.isSwiping) {
self.onSwipe(e);
} else if (self.isPanning) {
self.onPan();
} else if (self.isZooming) {
self.onZoom();
}
}
};
Guestures.prototype.onSwipe = function (e) {
var self = this,
instance = self.instance,
swiping = self.isSwiping,
left = self.sliderStartPos.left || 0,
angle;
// If direction is not yet determined
if (swiping === true) {
// We need at least 10px distance to correctly calculate an angle
if (Math.abs(self.distance) > 10) {
self.canTap = false;
if (instance.group.length < 2 && self.opts.vertical) {
self.isSwiping = "y";
} else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) {
self.isSwiping = "x";
} else {
angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);
self.isSwiping = angle > 45 && angle < 135 ? "y" : "x";
}
if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) {
self.isScrolling = true;
return;
}
instance.isDragging = self.isSwiping;
// Reset points to avoid jumping, because we dropped first swipes to calculate the angle
self.startPoints = self.newPoints;
$.each(instance.slides, function (index, slide) {
var slidePos, stagePos;
$.fancybox.stop(slide.$slide);
slidePos = $.fancybox.getTranslate(slide.$slide);
stagePos = $.fancybox.getTranslate(instance.$refs.stage);
slide.$slide
.css({
transform: "",
opacity: "",
"transition-duration": ""
})
.removeClass("fancybox-animated")
.removeClass(function (index, className) {
return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");
});
if (slide.pos === instance.current.pos) {
self.sliderStartPos.top = slidePos.top - stagePos.top;
self.sliderStartPos.left = slidePos.left - stagePos.left;
}
$.fancybox.setTranslate(slide.$slide, {
top: slidePos.top - stagePos.top,
left: slidePos.left - stagePos.left
});
});
// Stop slideshow
if (instance.SlideShow && instance.SlideShow.isActive) {
instance.SlideShow.stop();
}
}
return;
}
// Sticky edges
if (swiping == "x") {
if (
self.distanceX > 0 &&
(self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))
) {
left = left + Math.pow(self.distanceX, 0.8);
} else if (
self.distanceX < 0 &&
(self.instance.group.length < 2 ||
(self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))
) {
left = left - Math.pow(-self.distanceX, 0.8);
} else {
left = left + self.distanceX;
}
}
self.sliderLastPos = {
top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY,
left: left
};
if (self.requestId) {
cancelAFrame(self.requestId);
self.requestId = null;
}
self.requestId = requestAFrame(function () {
if (self.sliderLastPos) {
$.each(self.instance.slides, function (index, slide) {
var pos = slide.pos - self.instance.currPos;
$.fancybox.setTranslate(slide.$slide, {
top: self.sliderLastPos.top,
left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter
});
});
self.$container.addClass("fancybox-is-sliding");
}
});
};
Guestures.prototype.onPan = function () {
var self = this;
// Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)
if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {
self.startPoints = self.newPoints;
return;
}
self.canTap = false;
self.contentLastPos = self.limitMovement();
if (self.requestId) {
cancelAFrame(self.requestId);
}
self.requestId = requestAFrame(function () {
$.fancybox.setTranslate(self.$content, self.contentLastPos);
});
};
// Make panning sticky to the edges
Guestures.prototype.limitMovement = function () {
var self = this;
var canvasWidth = self.canvasWidth;
var canvasHeight = self.canvasHeight;
var distanceX = self.distanceX;
var distanceY = self.distanceY;
var contentStartPos = self.contentStartPos;
var currentOffsetX = contentStartPos.left;
var currentOffsetY = contentStartPos.top;
var currentWidth = contentStartPos.width;
var currentHeight = contentStartPos.height;
var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;
if (currentWidth > canvasWidth) {
newOffsetX = currentOffsetX + distanceX;
} else {
newOffsetX = currentOffsetX;
}
newOffsetY = currentOffsetY + distanceY;
// Slow down proportionally to traveled distance
minTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);
minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);
maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);
maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);
// ->
if (distanceX > 0 && newOffsetX > minTranslateX) {
newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;
}
// <-
if (distanceX < 0 && newOffsetX < maxTranslateX) {
newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;
}
// \/
if (distanceY > 0 && newOffsetY > minTranslateY) {
newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;
}
// /\
if (distanceY < 0 && newOffsetY < maxTranslateY) {
newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;
}
return {
top: newOffsetY,
left: newOffsetX
};
};
Guestures.prototype.limitPosition = function (newOffsetX, newOffsetY, newWidth, newHeight) {
var self = this;
var canvasWidth = self.canvasWidth;
var canvasHeight = self.canvasHeight;
if (newWidth > canvasWidth) {
newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;
newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;
} else {
// Center horizontally
newOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);
}
if (newHeight > canvasHeight) {
newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;
newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;
} else {
// Center vertically
newOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);
}
return {
top: newOffsetY,
left: newOffsetX
};
};
Guestures.prototype.onZoom = function () {
var self = this;
// Calculate current distance between points to get pinch ratio and new width and height
var contentStartPos = self.contentStartPos;
var currentWidth = contentStartPos.width;
var currentHeight = contentStartPos.height;
var currentOffsetX = contentStartPos.left;
var currentOffsetY = contentStartPos.top;
var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);
var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;
var newWidth = Math.floor(currentWidth * pinchRatio);
var newHeight = Math.floor(currentHeight * pinchRatio);
// This is the translation due to pinch-zooming
var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;
var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;
// Point between the two touches
var centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();
var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();
// And this is the translation due to translation of the centerpoint
// between the two fingers
var translateFromTranslatingX = centerPointEndX - self.centerPointStartX;
var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;
// The new offset is the old/current one plus the total translation
var newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);
var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);
var newPos = {
top: newOffsetY,
left: newOffsetX,
scaleX: pinchRatio,
scaleY: pinchRatio
};
self.canTap = false;
self.newWidth = newWidth;
self.newHeight = newHeight;
self.contentLastPos = newPos;
if (self.requestId) {
cancelAFrame(self.requestId);
}
self.requestId = requestAFrame(function () {
$.fancybox.setTranslate(self.$content, self.contentLastPos);
});
};
Guestures.prototype.ontouchend = function (e) {
var self = this;
var swiping = self.isSwiping;
var panning = self.isPanning;
var zooming = self.isZooming;
var scrolling = self.isScrolling;
self.endPoints = getPointerXY(e);
self.dMs = Math.max(new Date().getTime() - self.startTime, 1);
self.$container.removeClass("fancybox-is-grabbing");
$(document).off(".fb.touch");
document.removeEventListener("scroll", self.onscroll, true);
if (self.requestId) {
cancelAFrame(self.requestId);
self.requestId = null;
}
self.isSwiping = false;
self.isPanning = false;
self.isZooming = false;
self.isScrolling = false;
self.instance.isDragging = false;
if (self.canTap) {
return self.onTap(e);
}
self.speed = 100;
// Speed in px/ms
self.velocityX = (self.distanceX / self.dMs) * 0.5;
self.velocityY = (self.distanceY / self.dMs) * 0.5;
if (panning) {
self.endPanning();
} else if (zooming) {
self.endZooming();
} else {
self.endSwiping(swiping, scrolling);
}
return;
};
Guestures.prototype.endSwiping = function (swiping, scrolling) {
var self = this,
ret = false,
len = self.instance.group.length,
distanceX = Math.abs(self.distanceX),
canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),
speedX = 300;
self.sliderLastPos = null;
// Close if swiped vertically / navigate if horizontally
if (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) {
// Continue vertical movement
$.fancybox.animate(
self.instance.current.$slide, {
top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,
opacity: 0
},
200
);
ret = self.instance.close(true, 250);
} else if (canAdvance && self.distanceX > 0) {
ret = self.instance.previous(speedX);
} else if (canAdvance && self.distanceX < 0) {
ret = self.instance.next(speedX);
}
if (ret === false && (swiping == "x" || swiping == "y")) {
self.instance.centerSlide(200);
}
self.$container.removeClass("fancybox-is-sliding");
};
// Limit panning from edges
// ========================
Guestures.prototype.endPanning = function () {
var self = this,
newOffsetX,
newOffsetY,
newPos;
if (!self.contentLastPos) {
return;
}
if (self.opts.momentum === false || self.dMs > 350) {
newOffsetX = self.contentLastPos.left;
newOffsetY = self.contentLastPos.top;
} else {
// Continue movement
newOffsetX = self.contentLastPos.left + self.velocityX * 500;
newOffsetY = self.contentLastPos.top + self.velocityY * 500;
}
newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);
newPos.width = self.contentStartPos.width;
newPos.height = self.contentStartPos.height;
$.fancybox.animate(self.$content, newPos, 366);
};
Guestures.prototype.endZooming = function () {
var self = this;
var current = self.instance.current;
var newOffsetX, newOffsetY, newPos, reset;
var newWidth = self.newWidth;
var newHeight = self.newHeight;
if (!self.contentLastPos) {
return;
}
newOffsetX = self.contentLastPos.left;
newOffsetY = self.contentLastPos.top;
reset = {
top: newOffsetY,
left: newOffsetX,
width: newWidth,
height: newHeight,
scaleX: 1,
scaleY: 1
};
// Reset scalex/scaleY values; this helps for perfomance and does not break animation
$.fancybox.setTranslate(self.$content, reset);
if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {
self.instance.scaleToFit(150);
} else if (newWidth > current.width || newHeight > current.height) {
self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);
} else {
newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);
$.fancybox.animate(self.$content, newPos, 150);
}
};
Guestures.prototype.onTap = function (e) {
var self = this;
var $target = $(e.target);
var instance = self.instance;
var current = instance.current;
var endPoints = (e && getPointerXY(e)) || self.startPoints;
var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;
var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;
var where;
var process = function (prefix) {
var action = current.opts[prefix];
if ($.isFunction(action)) {
action = action.apply(instance, [current, e]);
}
if (!action) {
return;
}
switch (action) {
case "close":
instance.close(self.startEvent);
break;
case "toggleControls":
instance.toggleControls();
break;
case "next":
instance.next();
break;
case "nextOrClose":
if (instance.group.length > 1) {
instance.next();
} else {
instance.close(self.startEvent);
}
break;
case "zoom":
if (current.type == "image" && (current.isLoaded || current.$ghost)) {
if (instance.canPan()) {
instance.scaleToFit();
} else if (instance.isScaledDown()) {
instance.scaleToActual(tapX, tapY);
} else if (instance.group.length < 2) {
instance.close(self.startEvent);
}
}
break;
}
};
// Ignore right click
if (e.originalEvent && e.originalEvent.button == 2) {
return;
}
// Skip if clicked on the scrollbar
if (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) {
return;
}
// Check where is clicked
if ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) {
where = "Outside";
} else if ($target.is(".fancybox-slide")) {
where = "Slide";
} else if (
instance.current.$content &&
instance.current.$content
.find($target)
.addBack()
.filter($target).length
) {
where = "Content";
} else {
return;
}
// Check if this is a double tap
if (self.tapped) {
// Stop previously created single tap
clearTimeout(self.tapped);
self.tapped = null;
// Skip if distance between taps is too big
if (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {
return this;
}
// OK, now we assume that this is a double-tap
process("dblclick" + where);
} else {
// Single tap will be processed if user has not clicked second time within 300ms
// or there is no need to wait for double-tap
self.tapX = tapX;
self.tapY = tapY;
if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) {
self.tapped = setTimeout(function () {
self.tapped = null;
if (!instance.isAnimating) {
process("click" + where);
}
}, 500);
} else {
process("click" + where);
}
}
return this;
};
$(document)
.on("onActivate.fb", function (e, instance) {
if (instance && !instance.Guestures) {
instance.Guestures = new Guestures(instance);
}
})
.on("beforeClose.fb", function (e, instance) {
if (instance && instance.Guestures) {
instance.Guestures.destroy();
}
});
})(window, document, jQuery);
// ==========================================================================
//
// SlideShow
// Enables slideshow functionality
//
// Example of usage:
// $.fancybox.getInstance().SlideShow.start()
//
// ==========================================================================
(function (document, $) {
"use strict";
$.extend(true, $.fancybox.defaults, {
btnTpl: {
slideShow: '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg>' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg>' +
"</button>"
},
slideShow: {
autoStart: false,
speed: 3000,
progress: true
}
});
var SlideShow = function (instance) {
this.instance = instance;
this.init();
};
$.extend(SlideShow.prototype, {
timer: null,
isActive: false,
$button: null,
init: function () {
var self = this,
instance = self.instance,
opts = instance.group[instance.currIndex].opts.slideShow;
self.$button = instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function () {
self.toggle();
});
if (instance.group.length < 2 || !opts) {
self.$button.hide();
} else if (opts.progress) {
self.$progress = $('<div class="fancybox-progress"></div>').appendTo(instance.$refs.inner);
}
},
set: function (force) {
var self = this,
instance = self.instance,
current = instance.current;
// Check if reached last element
if (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {
if (self.isActive && current.contentType !== "video") {
if (self.$progress) {
$.fancybox.animate(self.$progress.show(), {
scaleX: 1
}, current.opts.slideShow.speed);
}
self.timer = setTimeout(function () {
if (!instance.current.opts.loop && instance.current.index == instance.group.length - 1) {
instance.jumpTo(0);
} else {
instance.next();
}
}, current.opts.slideShow.speed);
}
} else {
self.stop();
instance.idleSecondsCounter = 0;
instance.showControls();
}
},
clear: function () {
var self = this;
clearTimeout(self.timer);
self.timer = null;
if (self.$progress) {
self.$progress.removeAttr("style").hide();
}
},
start: function () {
var self = this,
current = self.instance.current;
if (current) {
self.$button
.attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_STOP)
.removeClass("fancybox-button--play")
.addClass("fancybox-button--pause");
self.isActive = true;
if (current.isComplete) {
self.set(true);
}
self.instance.trigger("onSlideShowChange", true);
}
},
stop: function () {
var self = this,
current = self.instance.current;
self.clear();
self.$button
.attr("title", (current.opts.i18n[current.opts.lang] || current.opts.i18n.en).PLAY_START)
.removeClass("fancybox-button--pause")
.addClass("fancybox-button--play");
self.isActive = false;
self.instance.trigger("onSlideShowChange", false);
if (self.$progress) {
self.$progress.removeAttr("style").hide();
}
},
toggle: function () {
var self = this;
if (self.isActive) {
self.stop();
} else {
self.start();
}
}
});
$(document).on({
"onInit.fb": function (e, instance) {
if (instance && !instance.SlideShow) {
instance.SlideShow = new SlideShow(instance);
}
},
"beforeShow.fb": function (e, instance, current, firstRun) {
var SlideShow = instance && instance.SlideShow;
if (firstRun) {
if (SlideShow && current.opts.slideShow.autoStart) {
SlideShow.start();
}
} else if (SlideShow && SlideShow.isActive) {
SlideShow.clear();
}
},
"afterShow.fb": function (e, instance, current) {
var SlideShow = instance && instance.SlideShow;
if (SlideShow && SlideShow.isActive) {
SlideShow.set();
}
},
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
var SlideShow = instance && instance.SlideShow;
// "P" or Spacebar
if (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) {
keypress.preventDefault();
SlideShow.toggle();
}
},
"beforeClose.fb onDeactivate.fb": function (e, instance) {
var SlideShow = instance && instance.SlideShow;
if (SlideShow) {
SlideShow.stop();
}
}
});
// Page Visibility API to pause slideshow when window is not active
$(document).on("visibilitychange", function () {
var instance = $.fancybox.getInstance(),
SlideShow = instance && instance.SlideShow;
if (SlideShow && SlideShow.isActive) {
if (document.hidden) {
SlideShow.clear();
} else {
SlideShow.set();
}
}
});
})(document, jQuery);
// ==========================================================================
//
// FullScreen
// Adds fullscreen functionality
//
// ==========================================================================
(function (document, $) {
"use strict";
// Collection of methods supported by user browser
var fn = (function () {
var fnMap = [
["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"],
// new WebKit
[
"webkitRequestFullscreen",
"webkitExitFullscreen",
"webkitFullscreenElement",
"webkitFullscreenEnabled",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
// old WebKit (Safari 5.1)
[
"webkitRequestFullScreen",
"webkitCancelFullScreen",
"webkitCurrentFullScreenElement",
"webkitCancelFullScreen",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
[
"mozRequestFullScreen",
"mozCancelFullScreen",
"mozFullScreenElement",
"mozFullScreenEnabled",
"mozfullscreenchange",
"mozfullscreenerror"
],
["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"]
];
var ret = {};
for (var i = 0; i < fnMap.length; i++) {
var val = fnMap[i];
if (val && val[1] in document) {
for (var j = 0; j < val.length; j++) {
ret[fnMap[0][j]] = val[j];
}
return ret;
}
}
return false;
})();
if (fn) {
var FullScreen = {
request: function (elem) {
elem = elem || document.documentElement;
elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);
},
exit: function () {
document[fn.exitFullscreen]();
},
toggle: function (elem) {
elem = elem || document.documentElement;
if (this.isFullscreen()) {
this.exit();
} else {
this.request(elem);
}
},
isFullscreen: function () {
return Boolean(document[fn.fullscreenElement]);
},
enabled: function () {
return Boolean(document[fn.fullscreenEnabled]);
}
};
$.extend(true, $.fancybox.defaults, {
btnTpl: {
fullScreen: '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg>' +
"</button>"
},
fullScreen: {
autoStart: false
}
});
$(document).on(fn.fullscreenchange, function () {
var isFullscreen = FullScreen.isFullscreen(),
instance = $.fancybox.getInstance();
if (instance) {
// If image is zooming, then force to stop and reposition properly
if (instance.current && instance.current.type === "image" && instance.isAnimating) {
instance.isAnimating = false;
instance.update(true, true, 0);
if (!instance.isComplete) {
instance.complete();
}
}
instance.trigger("onFullscreenChange", isFullscreen);
instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen);
instance.$refs.toolbar
.find("[data-fancybox-fullscreen]")
.toggleClass("fancybox-button--fsenter", !isFullscreen)
.toggleClass("fancybox-button--fsexit", isFullscreen);
}
});
}
$(document).on({
"onInit.fb": function (e, instance) {
var $container;
if (!fn) {
instance.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();
return;
}
if (instance && instance.group[instance.currIndex].opts.fullScreen) {
$container = instance.$refs.container;
$container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function (e) {
e.stopPropagation();
e.preventDefault();
FullScreen.toggle();
});
if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {
FullScreen.request();
}
// Expose API
instance.FullScreen = FullScreen;
} else if (instance) {
instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide();
}
},
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
// "F"
if (instance && instance.FullScreen && keycode === 70) {
keypress.preventDefault();
instance.FullScreen.toggle();
}
},
"beforeClose.fb": function (e, instance) {
if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) {
FullScreen.exit();
}
}
});
})(document, jQuery);
// ==========================================================================
//
// Thumbs
// Displays thumbnails in a grid
//
// ==========================================================================
(function (document, $) {
"use strict";
var CLASS = "fancybox-thumbs",
CLASS_ACTIVE = CLASS + "-active";
// Make sure there are default values
$.fancybox.defaults = $.extend(
true, {
btnTpl: {
thumbs: '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg>' +
"</button>"
},
thumbs: {
autoStart: false, // Display thumbnails on opening
hideOnClose: true, // Hide thumbnail grid when closing animation starts
parentEl: ".fancybox-container", // Container is injected into this element
axis: "y" // Vertical (y) or horizontal (x) scrolling
}
},
$.fancybox.defaults
);
var FancyThumbs = function (instance) {
this.init(instance);
};
$.extend(FancyThumbs.prototype, {
$button: null,
$grid: null,
$list: null,
isVisible: false,
isActive: false,
init: function (instance) {
var self = this,
group = instance.group,
enabled = 0;
self.instance = instance;
self.opts = group[instance.currIndex].opts.thumbs;
instance.Thumbs = self;
self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]");
// Enable thumbs if at least two group items have thumbnails
for (var i = 0, len = group.length; i < len; i++) {
if (group[i].thumb) {
enabled++;
}
if (enabled > 1) {
break;
}
}
if (enabled > 1 && !!self.opts) {
self.$button.removeAttr("style").on("click", function () {
self.toggle();
});
self.isActive = true;
} else {
self.$button.hide();
}
},
create: function () {
var self = this,
instance = self.instance,
parentEl = self.opts.parentEl,
list = [],
src;
if (!self.$grid) {
// Create main element
self.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo(
instance.$refs.container
.find(parentEl)
.addBack()
.filter(parentEl)
);
// Add "click" event that performs gallery navigation
self.$grid.on("click", "a", function () {
instance.jumpTo($(this).attr("data-index"));
});
}
// Build the list
if (!self.$list) {
self.$list = $('<div class="' + CLASS + '__list">').appendTo(self.$grid);
}
$.each(instance.group, function (i, item) {
src = item.thumb;
if (!src && item.type === "image") {
src = item.src;
}
list.push(
'<a href="javascript:;" tabindex="0" data-index="' +
i +
'"' +
(src && src.length ? ' style="background-image:url(' + src + ')"' : 'class="fancybox-thumbs-missing"') +
"></a>"
);
});
self.$list[0].innerHTML = list.join("");
if (self.opts.axis === "x") {
// Set fixed width for list element to enable horizontal scrolling
self.$list.width(
parseInt(self.$grid.css("padding-right"), 10) +
instance.group.length *
self.$list
.children()
.eq(0)
.outerWidth(true)
);
}
},
focus: function (duration) {
var self = this,
$list = self.$list,
$grid = self.$grid,
thumb,
thumbPos;
if (!self.instance.current) {
return;
}
thumb = $list
.children()
.removeClass(CLASS_ACTIVE)
.filter('[data-index="' + self.instance.current.index + '"]')
.addClass(CLASS_ACTIVE);
thumbPos = thumb.position();
// Check if need to scroll to make current thumb visible
if (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {
$list.stop().animate({
scrollTop: $list.scrollTop() + thumbPos.top
},
duration
);
} else if (
self.opts.axis === "x" &&
(thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))
) {
$list
.parent()
.stop()
.animate({
scrollLeft: thumbPos.left
},
duration
);
}
},
update: function () {
var that = this;
that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible);
if (that.isVisible) {
if (!that.$grid) {
that.create();
}
that.instance.trigger("onThumbsShow");
that.focus(0);
} else if (that.$grid) {
that.instance.trigger("onThumbsHide");
}
// Update content position
that.instance.update();
},
hide: function () {
this.isVisible = false;
this.update();
},
show: function () {
this.isVisible = true;
this.update();
},
toggle: function () {
this.isVisible = !this.isVisible;
this.update();
}
});
$(document).on({
"onInit.fb": function (e, instance) {
var Thumbs;
if (instance && !instance.Thumbs) {
Thumbs = new FancyThumbs(instance);
if (Thumbs.isActive && Thumbs.opts.autoStart === true) {
Thumbs.show();
}
}
},
"beforeShow.fb": function (e, instance, item, firstRun) {
var Thumbs = instance && instance.Thumbs;
if (Thumbs && Thumbs.isVisible) {
Thumbs.focus(firstRun ? 0 : 250);
}
},
"afterKeydown.fb": function (e, instance, current, keypress, keycode) {
var Thumbs = instance && instance.Thumbs;
// "G"
if (Thumbs && Thumbs.isActive && keycode === 71) {
keypress.preventDefault();
Thumbs.toggle();
}
},
"beforeClose.fb": function (e, instance) {
var Thumbs = instance && instance.Thumbs;
if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {
Thumbs.$grid.hide();
}
}
});
})(document, jQuery);
//// ==========================================================================
//
// Share
// Displays simple form for sharing current url
//
// ==========================================================================
(function (document, $) {
"use strict";
$.extend(true, $.fancybox.defaults, {
btnTpl: {
share: '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' +
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg>' +
"</button>"
},
share: {
url: function (instance, item) {
return (
(!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location
);
},
tpl: '<div class="fancybox-share">' +
"<h1>{{SHARE}}</h1>" +
"<p>" +
'<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' +
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' +
"<span>Facebook</span>" +
"</a>" +
'<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' +
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' +
"<span>Twitter</span>" +
"</a>" +
'<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' +
'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' +
"<span>Pinterest</span>" +
"</a>" +
"</p>" +
'<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p>' +
"</div>"
}
});
function escapeHtml(string) {
var entityMap = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;",
"/": "&#x2F;",
"`": "&#x60;",
"=": "&#x3D;"
};
return String(string).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
}
$(document).on("click", "[data-fancybox-share]", function () {
var instance = $.fancybox.getInstance(),
current = instance.current || null,
url,
tpl;
if (!current) {
return;
}
if ($.type(current.opts.share.url) === "function") {
url = current.opts.share.url.apply(current, [instance, current]);
}
tpl = current.opts.share.tpl
.replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "")
.replace(/\{\{url\}\}/g, encodeURIComponent(url))
.replace(/\{\{url_raw\}\}/g, escapeHtml(url))
.replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : "");
$.fancybox.open({
src: instance.translate(instance, tpl),
type: "html",
opts: {
touch: false,
animationEffect: false,
afterLoad: function (shareInstance, shareCurrent) {
// Close self if parent instance is closing
instance.$refs.container.one("beforeClose.fb", function () {
shareInstance.close(null, 0);
});
// Opening links in a popup window
shareCurrent.$content.find(".fancybox-share__button").click(function () {
window.open(this.href, "Share", "width=550, height=450");
return false;
});
},
mobile: {
autoFocus: false
}
}
});
});
})(document, jQuery);
// ==========================================================================
//
// Hash
// Enables linking to each modal
//
// ==========================================================================
(function (window, document, $) {
"use strict";
// Simple $.escapeSelector polyfill (for jQuery prior v3)
if (!$.escapeSelector) {
$.escapeSelector = function (sel) {
var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
var fcssescape = function (ch, asCodePoint) {
if (asCodePoint) {
// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
if (ch === "\0") {
return "\uFFFD";
}
// Control characters and (dependent upon position) numbers get escaped as code points
return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
}
// Other potentially-special ASCII characters get backslash-escaped
return "\\" + ch;
};
return (sel + "").replace(rcssescape, fcssescape);
};
}
// Get info about gallery name and current index from url
function parseUrl() {
var hash = window.location.hash.substr(1),
rez = hash.split("-"),
index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,
gallery = rez.join("-");
return {
hash: hash,
/* Index is starting from 1 */
index: index < 1 ? 1 : index,
gallery: gallery
};
}
// Trigger click evnt on links to open new fancyBox instance
function triggerFromUrl(url) {
if (url.gallery !== "") {
// If we can find element matching 'data-fancybox' atribute,
// then triggering click event should start fancyBox
$("[data-fancybox='" + $.escapeSelector(url.gallery) + "']")
.eq(url.index - 1)
.focus()
.trigger("click.fb-start");
}
}
// Get gallery name from current instance
function getGalleryID(instance) {
var opts, ret;
if (!instance) {
return false;
}
opts = instance.current ? instance.current.opts : instance.opts;
ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") || opts.$orig.data("fancybox-trigger") : "");
return ret === "" ? false : ret;
}
// Start when DOM becomes ready
$(function () {
// Check if user has disabled this module
if ($.fancybox.defaults.hash === false) {
return;
}
// Update hash when opening/closing fancyBox
$(document).on({
"onInit.fb": function (e, instance) {
var url, gallery;
if (instance.group[instance.currIndex].opts.hash === false) {
return;
}
url = parseUrl();
gallery = getGalleryID(instance);
// Make sure gallery start index matches index from hash
if (gallery && url.gallery && gallery == url.gallery) {
instance.currIndex = url.index - 1;
}
},
"beforeShow.fb": function (e, instance, current, firstRun) {
var gallery;
if (!current || current.opts.hash === false) {
return;
}
// Check if need to update window hash
gallery = getGalleryID(instance);
if (!gallery) {
return;
}
// Variable containing last hash value set by fancyBox
// It will be used to determine if fancyBox needs to close after hash change is detected
instance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : "");
// If current hash is the same (this instance most likely is opened by hashchange), then do nothing
if (window.location.hash === "#" + instance.currentHash) {
return;
}
if (firstRun && !instance.origHash) {
instance.origHash = window.location.hash;
}
if (instance.hashTimer) {
clearTimeout(instance.hashTimer);
}
// Update hash
instance.hashTimer = setTimeout(function () {
if ("replaceState" in window.history) {
window.history[firstRun ? "pushState" : "replaceState"]({},
document.title,
window.location.pathname + window.location.search + "#" + instance.currentHash
);
if (firstRun) {
instance.hasCreatedHistory = true;
}
} else {
window.location.hash = instance.currentHash;
}
instance.hashTimer = null;
}, 300);
},
"beforeClose.fb": function (e, instance, current) {
if (!current || current.opts.hash === false) {
return;
}
clearTimeout(instance.hashTimer);
// Goto previous history entry
if (instance.currentHash && instance.hasCreatedHistory) {
window.history.back();
} else if (instance.currentHash) {
if ("replaceState" in window.history) {
window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || ""));
} else {
window.location.hash = instance.origHash;
}
}
instance.currentHash = null;
}
});
// Check if need to start/close after url has changed
$(window).on("hashchange.fb", function () {
var url = parseUrl(),
fb = null;
// Find last fancyBox instance that has "hash"
$.each(
$(".fancybox-container")
.get()
.reverse(),
function (index, value) {
var tmp = $(value).data("FancyBox");
if (tmp && tmp.currentHash) {
fb = tmp;
return false;
}
}
);
if (fb) {
// Now, compare hash values
if (fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {
fb.currentHash = null;
fb.close();
}
} else if (url.gallery !== "") {
triggerFromUrl(url);
}
});
// Check current hash and trigger click event on matching element to start fancyBox, if needed
setTimeout(function () {
if (!$.fancybox.getInstance()) {
triggerFromUrl(parseUrl());
}
}, 50);
});
})(window, document, jQuery);
// ==========================================================================
//
// Wheel
// Basic mouse weheel support for gallery navigation
//
// ==========================================================================
(function (document, $) {
"use strict";
var prevTime = new Date().getTime();
$(document).on({
"onInit.fb": function (e, instance, current) {
instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function (e) {
var current = instance.current,
currTime = new Date().getTime();
if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) {
return;
}
e.preventDefault();
e.stopPropagation();
if (current.$slide.hasClass("fancybox-animated")) {
return;
}
e = e.originalEvent || e;
if (currTime - prevTime < 250) {
return;
}
prevTime = currTime;
instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"]();
});
}
});
})(document, jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

15
fancybox/createrelease Executable file
View file

@ -0,0 +1,15 @@
MODULE=fancybox
cd ..
# old releases not needed anymore
mkdir -p $MODULE/dist
rm $MODULE/dist/*
# create release for actual version
zip -r9 $MODULE/dist/release.zip $MODULE/* -x $MODULE/dist/\* -x $MODULE/test/\* $MODULE/createrelease
echo dist/release.zip created.
cd $MODULE

60
fancybox/fancybox.php Normal file
View file

@ -0,0 +1,60 @@
<?php
/**
* Name: Fancybox
* Description: Open media attachments of posts into a fancybox overlay.
* Version: 1.05
* Author: Grischa Brockhaus <grischa@brockha.us>
* Status: Unsupported
*/
use Friendica\Core\Hook;
use Friendica\DI;
function fancybox_install()
{
Hook::register('head', __FILE__, 'fancybox_head');
Hook::register('footer', __FILE__, 'fancybox_footer');
Hook::register('prepare_body_final', __FILE__, 'fancybox_render');
}
function fancybox_head(string &$b)
{
DI::page()->registerStylesheet(__DIR__ . '/asset/fancybox/jquery.fancybox.min.css');
}
function fancybox_footer(string &$str)
{
DI::page()->registerFooterScript(__DIR__ . '/asset/fancybox/jquery.fancybox.min.js');
DI::page()->registerFooterScript(__DIR__ . '/asset/fancybox/fancybox.config.js');
}
function fancybox_render(array &$b){
$gallery = 'gallery-' . $b['item']['uri-id'] ?? random_int(1000000, 10000000);
// performWithEscapedBlocks escapes block defined with 2nd par pattern that won't be processed.
// We don't want to touch images in class="type-link":
$b['html'] = \Friendica\Util\Strings::performWithEscapedBlocks(
$b['html'],
'#<div class="type-link">.*?</div>#s',
function ($text) use ($gallery) {
// This processes images inlined in posts
// Frio / Vier hooks für lightbox are un-hooked in fancybox-config.js. So this works for them, too!
//if (!in_array(DI::appHelper()->getCurrentTheme(),['vier','frio']))
$text = preg_replace(
'#<a[^>]*href="([^"]*)"[^>]*>(<img[^>]*src="[^"]*"[^>]*>)</a>#',
'<a data-fancybox="' . $gallery . '" href="$1">$2</a>',
$text);
// Local content images attached:
$text = preg_replace_callback(
'#<div class="(body-attach|imagegrid-column)">.*?</div>#s',
function ($matches) use ($gallery) {
return str_replace('<a href', '<a data-fancybox="' . $gallery . '" href', $matches[0]);
},
$text
);
return $text;
}
);
}

View file

@ -0,0 +1,47 @@
# ADDON forumdirectory
# Copyright (C)
# This file is distributed under the same license as the Friendica forumdirectory addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 12:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: forumdirectory.php:33 forumdirectory.php:137
msgid "Forum Directory"
msgstr ""
#: forumdirectory.php:53
msgid "Public access denied."
msgstr ""
#: forumdirectory.php:125
msgid "No entries (some entries may be hidden)."
msgstr ""
#: forumdirectory.php:131
msgid "Global Directory"
msgstr ""
#: forumdirectory.php:133
msgid "Find on this site"
msgstr ""
#: forumdirectory.php:135
msgid "Results for:"
msgstr ""
#: forumdirectory.php:139
msgid "Find"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,47 @@
# ADDON forumdirectory
# Copyright (C)
# This file is distributed under the same license as the Friendica forumdirectory addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 12:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: forumdirectory.php:33 forumdirectory.php:137
msgid "Forum Directory"
msgstr ""
#: forumdirectory.php:53
msgid "Public access denied."
msgstr ""
#: forumdirectory.php:125
msgid "No entries (some entries may be hidden)."
msgstr ""
#: forumdirectory.php:131
msgid "Global Directory"
msgstr ""
#: forumdirectory.php:133
msgid "Find on this site"
msgstr ""
#: forumdirectory.php:135
msgid "Results for:"
msgstr ""
#: forumdirectory.php:139
msgid "Find"
msgstr ""

View file

@ -1,16 +1,7 @@
<?php
$a->strings["Public access denied."] = "Publika atingo ne permesita.";
$a->strings["Global Directory"] = "Tutmonda Katalogo";
$a->strings["Find on this site"] = "Trovi en ĉi retejo";
$a->strings["Finding: "] = "Trovata:";
$a->strings["Site Directory"] = "Reteja Katalogo";
$a->strings["Find"] = "Trovi";
$a->strings["Age: "] = "Aĝo:";
$a->strings["Gender: "] = "Sekso:";
$a->strings["Location:"] = "Loko:";
$a->strings["Gender:"] = "Sekso:";
$a->strings["Status:"] = "Stato:";
$a->strings["Homepage:"] = "Hejmpaĝo:";
$a->strings["About:"] = "Pri:";
$a->strings["No entries (some entries may be hidden)."] = "Neniom da afiŝoj (kelkaj afiŝoj eble ne estas videbla).";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,47 @@
# ADDON forumdirectory
# Copyright (C)
# This file is distributed under the same license as the Friendica forumdirectory addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 12:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: forumdirectory.php:33 forumdirectory.php:137
msgid "Forum Directory"
msgstr ""
#: forumdirectory.php:53
msgid "Public access denied."
msgstr ""
#: forumdirectory.php:125
msgid "No entries (some entries may be hidden)."
msgstr ""
#: forumdirectory.php:131
msgid "Global Directory"
msgstr ""
#: forumdirectory.php:133
msgid "Find on this site"
msgstr ""
#: forumdirectory.php:135
msgid "Results for:"
msgstr ""
#: forumdirectory.php:139
msgid "Find"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,47 @@
# ADDON forumdirectory
# Copyright (C)
# This file is distributed under the same license as the Friendica forumdirectory addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 12:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: forumdirectory.php:33 forumdirectory.php:137
msgid "Forum Directory"
msgstr ""
#: forumdirectory.php:53
msgid "Public access denied."
msgstr ""
#: forumdirectory.php:125
msgid "No entries (some entries may be hidden)."
msgstr ""
#: forumdirectory.php:131
msgid "Global Directory"
msgstr ""
#: forumdirectory.php:133
msgid "Find on this site"
msgstr ""
#: forumdirectory.php:135
msgid "Results for:"
msgstr ""
#: forumdirectory.php:139
msgid "Find"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,47 @@
# ADDON forumdirectory
# Copyright (C)
# This file is distributed under the same license as the Friendica forumdirectory addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-22 12:31+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: forumdirectory.php:33 forumdirectory.php:137
msgid "Forum Directory"
msgstr ""
#: forumdirectory.php:53
msgid "Public access denied."
msgstr ""
#: forumdirectory.php:125
msgid "No entries (some entries may be hidden)."
msgstr ""
#: forumdirectory.php:131
msgid "Global Directory"
msgstr ""
#: forumdirectory.php:133
msgid "Find on this site"
msgstr ""
#: forumdirectory.php:135
msgid "Results for:"
msgstr ""
#: forumdirectory.php:139
msgid "Find"
msgstr ""

View file

@ -1,16 +1,7 @@
<?php
$a->strings["Public access denied."] = "Alemennings aðgangur ekki veittur.";
$a->strings["Global Directory"] = "Heims tengiliða skrá";
$a->strings["Find on this site"] = "Leita á þessum vef";
$a->strings["Finding: "] = "Niðurstöður:";
$a->strings["Site Directory"] = "Vef tengiliða skrá";
$a->strings["Find"] = "Finna";
$a->strings["Age: "] = "Aldur:";
$a->strings["Gender: "] = "Kyn:";
$a->strings["Location:"] = "Staðsetning:";
$a->strings["Gender:"] = "Kyn:";
$a->strings["Status:"] = "Staða:";
$a->strings["Homepage:"] = "Heimasíða:";
$a->strings["About:"] = "Um:";
$a->strings["No entries (some entries may be hidden)."] = "Engar færslur (sumar geta verið faldar).";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -7,9 +7,7 @@
*
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
@ -18,7 +16,7 @@ function fromapp_install()
Hook::register('post_local', 'addon/fromapp/fromapp.php', 'fromapp_post_hook');
Hook::register('addon_settings', 'addon/fromapp/fromapp.php', 'fromapp_settings');
Hook::register('addon_settings_post', 'addon/fromapp/fromapp.php', 'fromapp_settings_post');
Logger::notice("installed fromapp");
DI::logger()->notice("installed fromapp");
}
function fromapp_settings_post($post)
@ -76,6 +74,6 @@ function fromapp_post_hook(&$item)
$apps = explode(',', $app);
$item['app'] = trim($apps[mt_rand(0, count($apps)-1)]);
return;
}

View file

@ -0,0 +1,34 @@
# ADDON fromapp
# Copyright (C)
# This file is distributed under the same license as the Friendica fromapp addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 12:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: fromapp.php:45
msgid ""
"The application name you would like to show your posts originating from. "
"Separate different app names with a comma. A random one will then be "
"selected for every posting."
msgstr ""
#: fromapp.php:46
msgid "Use this application name even if another application was used."
msgstr ""
#: fromapp.php:51
msgid "FromApp Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,34 @@
# ADDON fromapp
# Copyright (C)
# This file is distributed under the same license as the Friendica fromapp addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 12:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: fromapp.php:45
msgid ""
"The application name you would like to show your posts originating from. "
"Separate different app names with a comma. A random one will then be "
"selected for every posting."
msgstr ""
#: fromapp.php:46
msgid "Use this application name even if another application was used."
msgstr ""
#: fromapp.php:51
msgid "FromApp Settings"
msgstr ""

View file

@ -1,7 +1,7 @@
<?php
$a->strings["Fromapp settings updated."] = "";
$a->strings["FromApp Settings"] = "";
$a->strings["The application name you would like to show your posts originating from."] = "";
$a->strings["Use this application name even if another application was used."] = "";
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,34 @@
# ADDON fromapp
# Copyright (C)
# This file is distributed under the same license as the Friendica fromapp addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 12:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: fromapp.php:45
msgid ""
"The application name you would like to show your posts originating from. "
"Separate different app names with a comma. A random one will then be "
"selected for every posting."
msgstr ""
#: fromapp.php:46
msgid "Use this application name even if another application was used."
msgstr ""
#: fromapp.php:51
msgid "FromApp Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,34 @@
# ADDON fromapp
# Copyright (C)
# This file is distributed under the same license as the Friendica fromapp addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 12:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: fromapp.php:45
msgid ""
"The application name you would like to show your posts originating from. "
"Separate different app names with a comma. A random one will then be "
"selected for every posting."
msgstr ""
#: fromapp.php:46
msgid "Use this application name even if another application was used."
msgstr ""
#: fromapp.php:51
msgid "FromApp Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,34 @@
# ADDON fromapp
# Copyright (C)
# This file is distributed under the same license as the Friendica fromapp addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-22 12:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: fromapp.php:45
msgid ""
"The application name you would like to show your posts originating from. "
"Separate different app names with a comma. A random one will then be "
"selected for every posting."
msgstr ""
#: fromapp.php:46
msgid "Use this application name even if another application was used."
msgstr ""
#: fromapp.php:51
msgid "FromApp Settings"
msgstr ""

View file

@ -1,7 +1,7 @@
<?php
$a->strings["Fromapp settings updated."] = "";
$a->strings["FromApp Settings"] = "";
$a->strings["The application name you would like to show your posts originating from."] = "";
$a->strings["Use this application name even if another application was used."] = "";
$a->strings["Submit"] = "Senda inn";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -6,9 +6,7 @@
* Author: Michael Vogel <https://pirati.ca/profile/heluecht>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
@ -52,25 +50,25 @@ function geocoordinates_resolve_item(array &$item)
$s = DI::httpClient()->fetch('https://api.opencagedata.com/geocode/v1/json?q=' . $coords[0] . ',' . $coords[1] . '&key=' . $key . '&language=' . $language);
if (!$s) {
Logger::info('API could not be queried');
DI::logger()->info('API could not be queried');
return;
}
$data = json_decode($s);
if ($data->status->code != '200') {
Logger::info('API returned error ' . $data->status->code . ' ' . $data->status->message);
DI::logger()->info('API returned error ' . $data->status->code . ' ' . $data->status->message);
return;
}
if (($data->total_results == 0) || (count($data->results) == 0)) {
Logger::info('No results found for coordinates ' . $item['coord']);
DI::logger()->info('No results found for coordinates ' . $item['coord']);
return;
}
$item['location'] = $data->results[0]->formatted;
Logger::info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']);
DI::logger()->info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']);
if ($item['location'] != '') {
DI::cache()->set('geocoordinates:' . $language.':' . $coords[0] . '-' . $coords[1], $item['location']);

View file

@ -6,9 +6,7 @@
* Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Core\Config\Util\ConfigFileManager;
@ -35,7 +33,7 @@ function geonames_install()
function geonames_load_config(ConfigFileManager $loader)
{
DI::app()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
}
function geonames_post_hook(array &$item)
@ -46,7 +44,7 @@ function geonames_post_hook(array &$item)
* - The profile owner must have allowed our addon
*/
Logger::notice('geonames invoked');
DI::logger()->notice('geonames invoked');
if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */
return;

View file

@ -0,0 +1,33 @@
# ADDON geonames
# Copyright (C)
# This file is distributed under the same license as the Friendica geonames addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: geonames.php:135
msgid ""
"Replace numerical coordinates by the nearest populated location name in your"
" posts."
msgstr ""
#: geonames.php:136
msgid "Enable Geonames Addon"
msgstr ""
#: geonames.php:141
msgid "Geonames Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,34 @@
# ADDON geonames
# Copyright (C)
# This file is distributed under the same license as the Friendica geonames addon package.
#
#
# Translators:
# Rafael Garau, 2018
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:27+0000\n"
"Last-Translator: Rafael Garau, 2018\n"
"Language-Team: Catalan (http://app.transifex.com/Friendica/friendica/language/ca/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: geonames.php:135
msgid ""
"Replace numerical coordinates by the nearest populated location name in your"
" posts."
msgstr ""
#: geonames.php:136
msgid "Enable Geonames Addon"
msgstr "Activa els Ajustos de Geonoms"
#: geonames.php:141
msgid "Geonames Settings"
msgstr "Ajustos de Geonoms"

View file

@ -1,6 +1,9 @@
<?php
$a->strings["Geonames settings updated."] = "Actualitzada la configuració de Geonames.";
$a->strings["Geonames Settings"] = "Configuració de Geonames";
$a->strings["Enable Geonames Addon"] = "Habilitar Addon de Geonames";
$a->strings["Submit"] = "Enviar";
<?php
if(! function_exists("string_plural_select_ca")) {
function string_plural_select_ca($n){
$n = intval($n);
return intval($n != 1);
}}
$a->strings['Enable Geonames Addon'] = 'Activa els Ajustos de Geonoms';
$a->strings['Geonames Settings'] = 'Ajustos de Geonoms';

View file

@ -0,0 +1,33 @@
# ADDON geonames
# Copyright (C)
# This file is distributed under the same license as the Friendica geonames addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: geonames.php:135
msgid ""
"Replace numerical coordinates by the nearest populated location name in your"
" posts."
msgstr ""
#: geonames.php:136
msgid "Enable Geonames Addon"
msgstr ""
#: geonames.php:141
msgid "Geonames Settings"
msgstr ""

View file

@ -1,6 +1,7 @@
<?php
$a->strings["Geonames settings updated."] = "Ĝidatigis la Geonames agordojn.";
$a->strings["Geonames Settings"] = "Geonames Agordoj";
$a->strings["Enable Geonames Addon"] = "Ŝalti la Geonames Kromprogramon";
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,33 @@
# ADDON geonames
# Copyright (C)
# This file is distributed under the same license as the Friendica geonames addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: geonames.php:135
msgid ""
"Replace numerical coordinates by the nearest populated location name in your"
" posts."
msgstr ""
#: geonames.php:136
msgid "Enable Geonames Addon"
msgstr ""
#: geonames.php:141
msgid "Geonames Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,33 @@
# ADDON geonames
# Copyright (C)
# This file is distributed under the same license as the Friendica geonames addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:27+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: geonames.php:135
msgid ""
"Replace numerical coordinates by the nearest populated location name in your"
" posts."
msgstr ""
#: geonames.php:136
msgid "Enable Geonames Addon"
msgstr ""
#: geonames.php:141
msgid "Geonames Settings"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -4,13 +4,11 @@
* Description: Thread email comment notifications on Gmail and anonymise them
* Version: 1.0
* Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
*
*
*
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Notification;
@ -21,7 +19,7 @@ function gnot_install()
Hook::register('addon_settings_post', 'addon/gnot/gnot.php', 'gnot_settings_post');
Hook::register('enotify_mail', 'addon/gnot/gnot.php', 'gnot_enotify_mail');
Logger::notice("installed gnot");
DI::logger()->notice("installed gnot");
}
/**
@ -38,7 +36,7 @@ function gnot_settings_post($post) {
}
/**
* Called from the Addon Setting form.
* Called from the Addon Setting form.
* Add our own settings info to the page.
*/
function gnot_settings(array &$data)

38
gnot/lang/bg/messages.po Normal file
View file

@ -0,0 +1,38 @@
# ADDON gnot
# Copyright (C)
# This file is distributed under the same license as the Friendica gnot addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:30+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gnot.php:63
msgid ""
"Allows threading of email comment notifications on Gmail and anonymising the"
" subject line."
msgstr ""
#: gnot.php:64
msgid "Enable this addon?"
msgstr ""
#: gnot.php:69
msgid "Gnot Settings"
msgstr ""
#: gnot.php:79
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%d"
msgstr ""

7
gnot/lang/bg/strings.php Normal file
View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

38
gnot/lang/eo/messages.po Normal file
View file

@ -0,0 +1,38 @@
# ADDON gnot
# Copyright (C)
# This file is distributed under the same license as the Friendica gnot addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:30+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gnot.php:63
msgid ""
"Allows threading of email comment notifications on Gmail and anonymising the"
" subject line."
msgstr ""
#: gnot.php:64
msgid "Enable this addon?"
msgstr ""
#: gnot.php:69
msgid "Gnot Settings"
msgstr ""
#: gnot.php:79
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%d"
msgstr ""

View file

@ -1,8 +1,7 @@
<?php
$a->strings["Gnot settings updated."] = "Ĝisdatigis Gnot agordojn.";
$a->strings["Gnot Settings"] = "Agordoj por Gnot";
$a->strings["Allows threading of email comment notifications on Gmail and anonymising the subject line."] = "Permesas la ĉenadon de retpoŝtaj atentigoj pri komentoj ĉe Gmail kan anonimigado de la temlinio.";
$a->strings["Enable this addon?"] = "Ŝalti tiun kromprogramon?";
$a->strings["Submit"] = "Sendi";
$a->strings["[Friendica:Notify] Comment to conversation #%d"] = "[Friendica:Atentigo] Komento pri konversacio #%d";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

39
gnot/lang/et/messages.po Normal file
View file

@ -0,0 +1,39 @@
# ADDON gnot
# Copyright (C)
# This file is distributed under the same license as the Friendica gnot addon package.
#
#
# Translators:
# Rain Hawk, 2020
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:30+0000\n"
"Last-Translator: Rain Hawk, 2020\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gnot.php:63
msgid ""
"Allows threading of email comment notifications on Gmail and anonymising the"
" subject line."
msgstr ""
#: gnot.php:64
msgid "Enable this addon?"
msgstr ""
#: gnot.php:69
msgid "Gnot Settings"
msgstr ""
#: gnot.php:79
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%d"
msgstr ""

7
gnot/lang/et/strings.php Normal file
View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

38
gnot/lang/gd/messages.po Normal file
View file

@ -0,0 +1,38 @@
# ADDON gnot
# Copyright (C)
# This file is distributed under the same license as the Friendica gnot addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:30+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: gnot.php:63
msgid ""
"Allows threading of email comment notifications on Gmail and anonymising the"
" subject line."
msgstr ""
#: gnot.php:64
msgid "Enable this addon?"
msgstr ""
#: gnot.php:69
msgid "Gnot Settings"
msgstr ""
#: gnot.php:79
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%d"
msgstr ""

7
gnot/lang/gd/strings.php Normal file
View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

38
gnot/lang/is/messages.po Normal file
View file

@ -0,0 +1,38 @@
# ADDON gnot
# Copyright (C)
# This file is distributed under the same license as the Friendica gnot addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:30+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: gnot.php:63
msgid ""
"Allows threading of email comment notifications on Gmail and anonymising the"
" subject line."
msgstr ""
#: gnot.php:64
msgid "Enable this addon?"
msgstr ""
#: gnot.php:69
msgid "Gnot Settings"
msgstr ""
#: gnot.php:79
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%d"
msgstr ""

View file

@ -1,8 +1,7 @@
<?php
$a->strings["Gnot settings updated."] = "";
$a->strings["Gnot Settings"] = "";
$a->strings["Allows threading of email comment notifications on Gmail and anonymising the subject line."] = "";
$a->strings["Enable this addon?"] = "";
$a->strings["Submit"] = "Senda inn";
$a->strings["[Friendica:Notify] Comment to conversation #%d"] = "";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -7,15 +7,14 @@
*
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\DI;
function googlemaps_install()
{
Hook::register('render_location', 'addon/googlemaps/googlemaps.php', 'googlemaps_location');
Logger::notice('installed googlemaps');
DI::logger()->notice('installed googlemaps');
}
function googlemaps_location(&$item)

View file

@ -6,15 +6,11 @@
* Author: Klaus Weidenbach <http://friendica.dszdw.net/profile/klaus>
*/
use Friendica\App;
use Friendica\BaseModule;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Util\Strings;
/**
* Installs the addon hook
@ -23,12 +19,12 @@ function gravatar_install() {
Hook::register('load_config', 'addon/gravatar/gravatar.php', 'gravatar_load_config');
Hook::register('avatar_lookup', 'addon/gravatar/gravatar.php', 'gravatar_lookup');
Logger::notice("registered gravatar in avatar_lookup hook");
DI::logger()->notice("registered gravatar in avatar_lookup hook");
}
function gravatar_load_config(ConfigFileManager $loader)
{
DI::app()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC);
}
/**

View file

@ -0,0 +1,70 @@
# ADDON gravatar
# Copyright (C)
# This file is distributed under the same license as the Friendica gravatar addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-23 08:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gravatar.php:78
msgid "generic profile image"
msgstr ""
#: gravatar.php:79
msgid "random geometric pattern"
msgstr ""
#: gravatar.php:80
msgid "monster face"
msgstr ""
#: gravatar.php:81
msgid "computer generated face"
msgstr ""
#: gravatar.php:82
msgid "retro arcade style face"
msgstr ""
#: gravatar.php:96
msgid "Information"
msgstr ""
#: gravatar.php:96
msgid ""
"Libravatar addon is installed, too. Please disable Libravatar addon or this "
"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
"nothing was found at Libravatar."
msgstr ""
#: gravatar.php:102
msgid "Save Settings"
msgstr ""
#: gravatar.php:103
msgid "Default avatar image"
msgstr ""
#: gravatar.php:103
msgid "Select default avatar image if none was found at Gravatar. See README"
msgstr ""
#: gravatar.php:104
msgid "Rating of images"
msgstr ""
#: gravatar.php:104
msgid "Select the appropriate avatar rating for your site. See README"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,70 @@
# ADDON gravatar
# Copyright (C)
# This file is distributed under the same license as the Friendica gravatar addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-23 08:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gravatar.php:78
msgid "generic profile image"
msgstr ""
#: gravatar.php:79
msgid "random geometric pattern"
msgstr ""
#: gravatar.php:80
msgid "monster face"
msgstr ""
#: gravatar.php:81
msgid "computer generated face"
msgstr ""
#: gravatar.php:82
msgid "retro arcade style face"
msgstr ""
#: gravatar.php:96
msgid "Information"
msgstr ""
#: gravatar.php:96
msgid ""
"Libravatar addon is installed, too. Please disable Libravatar addon or this "
"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
"nothing was found at Libravatar."
msgstr ""
#: gravatar.php:102
msgid "Save Settings"
msgstr ""
#: gravatar.php:103
msgid "Default avatar image"
msgstr ""
#: gravatar.php:103
msgid "Select default avatar image if none was found at Gravatar. See README"
msgstr ""
#: gravatar.php:104
msgid "Rating of images"
msgstr ""
#: gravatar.php:104
msgid "Select the appropriate avatar rating for your site. See README"
msgstr ""

View file

@ -1,15 +1,7 @@
<?php
$a->strings["generic profile image"] = "komuna profilbildo";
$a->strings["random geometric pattern"] = "loteca geometria skemo";
$a->strings["monster face"] = "monstrobildo";
$a->strings["computer generated face"] = "komputita vizaĝo";
$a->strings["retro arcade style face"] = "retrostila videoludstila vizaĝo";
$a->strings["Information"] = "Informo";
$a->strings["Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar."] = "La Libravatar kromprogramo estas ankaŭ instaltga. Bonvolu malŝalti la Libravatar kromprogramon.<br>La Libravatar kromprogramo retropaŝos al Gravatar se neniu troveblis ĉe Libravatar.";
$a->strings["Submit"] = "Sendi";
$a->strings["Default avatar image"] = "Defaŭlta avatarbildo";
$a->strings["Select default avatar image if none was found at Gravatar. See README"] = "Elektu defaŭltan avatarbildon se neniu troviĝis ĉe Gravatar. Vidu README.";
$a->strings["Rating of images"] = "Pritakso de bildoj";
$a->strings["Select the appropriate avatar rating for your site. See README"] = "Elektu la ĝustan pritakson de via avataro por via retejo. Vidu README.";
$a->strings["Gravatar settings updated."] = "Gravatar agordoj ĝisdatigitaj.";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,71 @@
# ADDON gravatar
# Copyright (C)
# This file is distributed under the same license as the Friendica gravatar addon package.
#
#
# Translators:
# Rain Hawk, 2020
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-23 08:33+0000\n"
"Last-Translator: Rain Hawk, 2020\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: gravatar.php:78
msgid "generic profile image"
msgstr ""
#: gravatar.php:79
msgid "random geometric pattern"
msgstr ""
#: gravatar.php:80
msgid "monster face"
msgstr ""
#: gravatar.php:81
msgid "computer generated face"
msgstr ""
#: gravatar.php:82
msgid "retro arcade style face"
msgstr ""
#: gravatar.php:96
msgid "Information"
msgstr ""
#: gravatar.php:96
msgid ""
"Libravatar addon is installed, too. Please disable Libravatar addon or this "
"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
"nothing was found at Libravatar."
msgstr ""
#: gravatar.php:102
msgid "Save Settings"
msgstr ""
#: gravatar.php:103
msgid "Default avatar image"
msgstr ""
#: gravatar.php:103
msgid "Select default avatar image if none was found at Gravatar. See README"
msgstr ""
#: gravatar.php:104
msgid "Rating of images"
msgstr ""
#: gravatar.php:104
msgid "Select the appropriate avatar rating for your site. See README"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,70 @@
# ADDON gravatar
# Copyright (C)
# This file is distributed under the same license as the Friendica gravatar addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-23 08:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: gravatar.php:78
msgid "generic profile image"
msgstr ""
#: gravatar.php:79
msgid "random geometric pattern"
msgstr ""
#: gravatar.php:80
msgid "monster face"
msgstr ""
#: gravatar.php:81
msgid "computer generated face"
msgstr ""
#: gravatar.php:82
msgid "retro arcade style face"
msgstr ""
#: gravatar.php:96
msgid "Information"
msgstr ""
#: gravatar.php:96
msgid ""
"Libravatar addon is installed, too. Please disable Libravatar addon or this "
"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
"nothing was found at Libravatar."
msgstr ""
#: gravatar.php:102
msgid "Save Settings"
msgstr ""
#: gravatar.php:103
msgid "Default avatar image"
msgstr ""
#: gravatar.php:103
msgid "Select default avatar image if none was found at Gravatar. See README"
msgstr ""
#: gravatar.php:104
msgid "Rating of images"
msgstr ""
#: gravatar.php:104
msgid "Select the appropriate avatar rating for your site. See README"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,70 @@
# ADDON gravatar
# Copyright (C)
# This file is distributed under the same license as the Friendica gravatar addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-02-01 18:15+0100\n"
"PO-Revision-Date: 2014-06-23 08:33+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: gravatar.php:78
msgid "generic profile image"
msgstr ""
#: gravatar.php:79
msgid "random geometric pattern"
msgstr ""
#: gravatar.php:80
msgid "monster face"
msgstr ""
#: gravatar.php:81
msgid "computer generated face"
msgstr ""
#: gravatar.php:82
msgid "retro arcade style face"
msgstr ""
#: gravatar.php:96
msgid "Information"
msgstr ""
#: gravatar.php:96
msgid ""
"Libravatar addon is installed, too. Please disable Libravatar addon or this "
"Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if "
"nothing was found at Libravatar."
msgstr ""
#: gravatar.php:102
msgid "Save Settings"
msgstr ""
#: gravatar.php:103
msgid "Default avatar image"
msgstr ""
#: gravatar.php:103
msgid "Select default avatar image if none was found at Gravatar. See README"
msgstr ""
#: gravatar.php:104
msgid "Rating of images"
msgstr ""
#: gravatar.php:104
msgid "Select the appropriate avatar rating for your site. See README"
msgstr ""

View file

@ -1,15 +1,7 @@
<?php
$a->strings["generic profile image"] = "";
$a->strings["random geometric pattern"] = "";
$a->strings["monster face"] = "";
$a->strings["computer generated face"] = "";
$a->strings["retro arcade style face"] = "";
$a->strings["Information"] = "";
$a->strings["Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.<br>The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar."] = "";
$a->strings["Submit"] = "Senda inn";
$a->strings["Default avatar image"] = "";
$a->strings["Select default avatar image if none was found at Gravatar. See README"] = "";
$a->strings["Rating of images"] = "";
$a->strings["Select the appropriate avatar rating for your site. See README"] = "";
$a->strings["Gravatar settings updated."] = "";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -8,9 +8,7 @@
* Note: Please use Circle Text instead
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;

View file

@ -0,0 +1,27 @@
# ADDON group_text
# Copyright (C)
# This file is distributed under the same license as the Friendica group_text addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Bulgarian (http://app.transifex.com/Friendica/friendica/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: group_text.php:58
msgid "Use a text only (non-image) group selector in the \"group edit\" menu"
msgstr ""
#: group_text.php:63
msgid "Group Text"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,27 @@
# ADDON group_text
# Copyright (C)
# This file is distributed under the same license as the Friendica group_text addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Esperanto (http://app.transifex.com/Friendica/friendica/language/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: group_text.php:58
msgid "Use a text only (non-image) group selector in the \"group edit\" menu"
msgstr ""
#: group_text.php:63
msgid "Group Text"
msgstr ""

View file

@ -1,5 +1,7 @@
<?php
$a->strings["Group Text"] = "";
$a->strings["Use a text only (non-image) group selector in the \"group edit\" menu"] = "";
$a->strings["Submit"] = "Sendi";
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,28 @@
# ADDON group_text
# Copyright (C)
# This file is distributed under the same license as the Friendica group_text addon package.
#
#
# Translators:
# Rain Hawk, 2020
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:35+0000\n"
"Last-Translator: Rain Hawk, 2020\n"
"Language-Team: Estonian (http://app.transifex.com/Friendica/friendica/language/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: group_text.php:58
msgid "Use a text only (non-image) group selector in the \"group edit\" menu"
msgstr ""
#: group_text.php:63
msgid "Group Text"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

View file

@ -0,0 +1,27 @@
# ADDON group_text
# Copyright (C)
# This file is distributed under the same license as the Friendica group_text addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Gaelic, Scottish (http://app.transifex.com/Friendica/friendica/language/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: group_text.php:58
msgid "Use a text only (non-image) group selector in the \"group edit\" menu"
msgstr ""
#: group_text.php:63
msgid "Group Text"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_gd")) {
function string_plural_select_gd($n){
$n = intval($n);
if (($n==1 || $n==11)) { return 0; } else if (($n==2 || $n==12)) { return 1; } else if (($n > 2 && $n < 20)) { return 2; } else { return 3; }
}}

View file

@ -0,0 +1,27 @@
# ADDON group_text
# Copyright (C)
# This file is distributed under the same license as the Friendica group_text addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:14-0500\n"
"PO-Revision-Date: 2014-06-23 08:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Icelandic (http://app.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: group_text.php:58
msgid "Use a text only (non-image) group selector in the \"group edit\" menu"
msgstr ""
#: group_text.php:63
msgid "Group Text"
msgstr ""

View file

@ -1,5 +1,7 @@
<?php
$a->strings["Group Text"] = "";
$a->strings["Use a text only (non-image) group selector in the \"group edit\" menu"] = "";
$a->strings["Submit"] = "Senda inn";
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return intval($n % 10 != 1 || $n % 100 == 11);
}}

View file

@ -6,7 +6,6 @@
* Author: Hypolite Petovan <hypolite@mrpetovan.com>
*/
use Friendica\App;
use Friendica\Core\Hook;
use Friendica\DI;
@ -18,7 +17,7 @@ function highlightjs_install()
function highlightjs_head(string &$str)
{
if (DI::app()->getCurrentTheme() == 'frio') {
if (DI::appHelper()->getCurrentTheme() == 'frio') {
$style = 'bootstrap';
} else {
$style = 'default';

View file

@ -6,10 +6,8 @@
* Version: 0.1
* Author: Michael Vogel <https://pirati.ca/profile/heluecht>
*/
use Friendica\App;
use Friendica\Content\PageInfo;
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\Core\Worker;
use Friendica\Database\DBA;
@ -87,16 +85,16 @@ function ifttt_post()
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $nickname]);
if (!DBA::isResult($user)) {
Logger::info('User ' . $nickname . ' not found.');
DI::logger()->info('User ' . $nickname . ' not found.');
return;
}
$uid = $user['uid'];
Logger::info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true));
DI::logger()->info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true));
if (!isset($_REQUEST['key'])) {
Logger::notice('No key found.');
DI::logger()->notice('No key found.');
return;
}
@ -104,7 +102,7 @@ function ifttt_post()
// Check the key
if ($key != DI::pConfig()->get($uid, 'ifttt', 'key')) {
Logger::info('Invalid key for user ' . $uid);
DI::logger()->info('Invalid key for user ' . $uid);
return;
}
@ -115,7 +113,7 @@ function ifttt_post()
}
if (!in_array($item['type'], ['status', 'link', 'photo'])) {
Logger::info('Unknown item type ' . $item['type']);
DI::logger()->info('Unknown item type ' . $item['type']);
return;
}

58
ifttt/lang/bg/messages.po Normal file
View file

@ -0,0 +1,58 @@
# ADDON ifttt
# Copyright (C)
# This file is distributed under the same license as the Friendica ifttt addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2017-11-27 10:37+0000\n"
"Language-Team: Bulgarian (https://app.transifex.com/Friendica/teams/12172/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ifttt.php:52
msgid ""
"Create an account at <a href=\"http://www.ifttt.com\">IFTTT</a>. Create "
"three Facebook recipes that are connected with <a "
"href=\"https://ifttt.com/maker\">Maker</a> (In the form \"if Facebook then "
"Maker\") with the following parameters:"
msgstr ""
#: ifttt.php:53
msgid "URL"
msgstr ""
#: ifttt.php:54
msgid "Method"
msgstr ""
#: ifttt.php:55
msgid "Content Type"
msgstr ""
#: ifttt.php:56
msgid "Body for \"new status message\""
msgstr ""
#: ifttt.php:57
msgid "Body for \"new photo upload\""
msgstr ""
#: ifttt.php:58
msgid "Body for \"new link post\""
msgstr ""
#: ifttt.php:68
msgid "IFTTT Mirror"
msgstr ""
#: ifttt.php:71
msgid "Generate new key"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_bg")) {
function string_plural_select_bg($n){
$n = intval($n);
return intval($n != 1);
}}

66
ifttt/lang/ca/messages.po Normal file
View file

@ -0,0 +1,66 @@
# ADDON ifttt
# Copyright (C)
# This file is distributed under the same license as the Friendica ifttt addon package.
#
#
# Translators:
# Rafael Garau, 2018
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2017-11-27 10:37+0000\n"
"Last-Translator: Rafael Garau, 2018\n"
"Language-Team: Catalan (https://app.transifex.com/Friendica/teams/12172/ca/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ifttt.php:52
msgid ""
"Create an account at <a href=\"http://www.ifttt.com\">IFTTT</a>. Create "
"three Facebook recipes that are connected with <a "
"href=\"https://ifttt.com/maker\">Maker</a> (In the form \"if Facebook then "
"Maker\") with the following parameters:"
msgstr ""
"Crear un compte en <a href=\"http://www.ifttt.com\">IFTTT</a>. Crear tres "
"fórmules per Facebook que estiguin connectades amb <a "
"href=\"https://ifttt.com/maker\">Maker</a> (de la següent forma \"si "
"Facebook llavors Maker\") amb els següents paràmetres:"
#: ifttt.php:53
msgid "URL"
msgstr ""
#: ifttt.php:54
msgid "Method"
msgstr ""
#: ifttt.php:55
msgid "Content Type"
msgstr ""
#: ifttt.php:56
msgid "Body for \"new status message\""
msgstr "Cos pel \"nou missatge de estatus\""
#: ifttt.php:57
msgid "Body for \"new photo upload\""
msgstr "Cos per la \"nova foto pujada\""
#: ifttt.php:58
msgid "Body for \"new link post\""
msgstr "Cos pel \"nou enllaç de l'enviament\""
#: ifttt.php:68
msgid "IFTTT Mirror"
msgstr "Espill IFTTT"
#: ifttt.php:71
msgid "Generate new key"
msgstr "Generar nova clau"

13
ifttt/lang/ca/strings.php Normal file
View file

@ -0,0 +1,13 @@
<?php
if(! function_exists("string_plural_select_ca")) {
function string_plural_select_ca($n){
$n = intval($n);
return intval($n != 1);
}}
$a->strings['Create an account at <a href="http://www.ifttt.com">IFTTT</a>. Create three Facebook recipes that are connected with <a href="https://ifttt.com/maker">Maker</a> (In the form "if Facebook then Maker") with the following parameters:'] = 'Crear un compte en <a href="http://www.ifttt.com">IFTTT</a>. Crear tres fórmules per Facebook que estiguin connectades amb <a href="https://ifttt.com/maker">Maker</a> (de la següent forma "si Facebook llavors Maker") amb els següents paràmetres:';
$a->strings['Body for "new status message"'] = 'Cos pel "nou missatge de estatus"';
$a->strings['Body for "new photo upload"'] = 'Cos per la "nova foto pujada"';
$a->strings['Body for "new link post"'] = 'Cos pel "nou enllaç de l\'enviament"';
$a->strings['IFTTT Mirror'] = 'Espill IFTTT';
$a->strings['Generate new key'] = 'Generar nova clau';

58
ifttt/lang/eo/messages.po Normal file
View file

@ -0,0 +1,58 @@
# ADDON ifttt
# Copyright (C)
# This file is distributed under the same license as the Friendica ifttt addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2017-11-27 10:37+0000\n"
"Language-Team: Esperanto (https://app.transifex.com/Friendica/teams/12172/eo/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eo\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ifttt.php:52
msgid ""
"Create an account at <a href=\"http://www.ifttt.com\">IFTTT</a>. Create "
"three Facebook recipes that are connected with <a "
"href=\"https://ifttt.com/maker\">Maker</a> (In the form \"if Facebook then "
"Maker\") with the following parameters:"
msgstr ""
#: ifttt.php:53
msgid "URL"
msgstr ""
#: ifttt.php:54
msgid "Method"
msgstr ""
#: ifttt.php:55
msgid "Content Type"
msgstr ""
#: ifttt.php:56
msgid "Body for \"new status message\""
msgstr ""
#: ifttt.php:57
msgid "Body for \"new photo upload\""
msgstr ""
#: ifttt.php:58
msgid "Body for \"new link post\""
msgstr ""
#: ifttt.php:68
msgid "IFTTT Mirror"
msgstr ""
#: ifttt.php:71
msgid "Generate new key"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_eo")) {
function string_plural_select_eo($n){
$n = intval($n);
return intval($n != 1);
}}

58
ifttt/lang/et/messages.po Normal file
View file

@ -0,0 +1,58 @@
# ADDON ifttt
# Copyright (C)
# This file is distributed under the same license as the Friendica ifttt addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2017-11-27 10:37+0000\n"
"Language-Team: Estonian (https://app.transifex.com/Friendica/teams/12172/et/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ifttt.php:52
msgid ""
"Create an account at <a href=\"http://www.ifttt.com\">IFTTT</a>. Create "
"three Facebook recipes that are connected with <a "
"href=\"https://ifttt.com/maker\">Maker</a> (In the form \"if Facebook then "
"Maker\") with the following parameters:"
msgstr ""
#: ifttt.php:53
msgid "URL"
msgstr ""
#: ifttt.php:54
msgid "Method"
msgstr ""
#: ifttt.php:55
msgid "Content Type"
msgstr ""
#: ifttt.php:56
msgid "Body for \"new status message\""
msgstr ""
#: ifttt.php:57
msgid "Body for \"new photo upload\""
msgstr ""
#: ifttt.php:58
msgid "Body for \"new link post\""
msgstr ""
#: ifttt.php:68
msgid "IFTTT Mirror"
msgstr ""
#: ifttt.php:71
msgid "Generate new key"
msgstr ""

View file

@ -0,0 +1,7 @@
<?php
if(! function_exists("string_plural_select_et")) {
function string_plural_select_et($n){
$n = intval($n);
return intval($n != 1);
}}

58
ifttt/lang/gd/messages.po Normal file
View file

@ -0,0 +1,58 @@
# ADDON ifttt
# Copyright (C)
# This file is distributed under the same license as the Friendica ifttt addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-21 19:17-0500\n"
"PO-Revision-Date: 2017-11-27 10:37+0000\n"
"Language-Team: Gaelic, Scottish (https://app.transifex.com/Friendica/teams/12172/gd/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: gd\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: ifttt.php:52
msgid ""
"Create an account at <a href=\"http://www.ifttt.com\">IFTTT</a>. Create "
"three Facebook recipes that are connected with <a "
"href=\"https://ifttt.com/maker\">Maker</a> (In the form \"if Facebook then "
"Maker\") with the following parameters:"
msgstr ""
#: ifttt.php:53
msgid "URL"
msgstr ""
#: ifttt.php:54
msgid "Method"
msgstr ""
#: ifttt.php:55
msgid "Content Type"
msgstr ""
#: ifttt.php:56
msgid "Body for \"new status message\""
msgstr ""
#: ifttt.php:57
msgid "Body for \"new photo upload\""
msgstr ""
#: ifttt.php:58
msgid "Body for \"new link post\""
msgstr ""
#: ifttt.php:68
msgid "IFTTT Mirror"
msgstr ""
#: ifttt.php:71
msgid "Generate new key"
msgstr ""

Some files were not shown because too many files have changed in this diff Show more