Compare commits

...

916 commits

Author SHA1 Message Date
sfr 5385797ff1 Smarter scope copy (#28)
Reviewed-on: AkkomaGang/pleroma-fe#28
Co-authored-by: sfr <sol@solfisher.com>
Co-committed-by: sfr <sol@solfisher.com>
2022-07-12 09:04:28 +00:00
floatingghost 7d377b8e88 Merge pull request '[#30] increase spacing of icons' (#31) from icon-spacing into develop
Reviewed-on: AkkomaGang/pleroma-fe#31
2022-07-10 17:11:44 +00:00
FloatingGhost 67bc9e5ba3 increase spacing of icons 2022-07-10 18:05:55 +01:00
floatingghost 3dac486688 Merge pull request 'refactor list search' (#27) from list-searcher into develop
Reviewed-on: AkkomaGang/pleroma-fe#27
2022-07-05 13:42:17 +00:00
FloatingGhost 88d04f0af7 also run search on checkbox update 2022-07-05 14:37:26 +01:00
FloatingGhost 617cd7d1f8 refactor list search 2022-07-05 14:28:23 +01:00
sfr 677e5325fa implement Move activities (#26)
Reviewed-on: AkkomaGang/pleroma-fe#26
Co-authored-by: sfr <sol@solfisher.com>
Co-committed-by: sfr <sol@solfisher.com>
2022-07-04 16:38:58 +00:00
floatingghost 101f15a078 Merge pull request 'fix search rendering' (#25) from mfm-search into develop
Reviewed-on: AkkomaGang/pleroma-fe#25
2022-07-01 12:50:44 +00:00
FloatingGhost 370f3b14fa fix search rendering 2022-07-01 13:50:14 +01:00
floatingghost 6e641a99a2 Show warning if a post has a subject line but is not marked as sensitive (#24)
Reviewed-on: AkkomaGang/pleroma-fe#24
2022-06-28 13:53:12 +00:00
sfr 716320de35 Respect subject lines in notifications (#23)
Reviewed-on: AkkomaGang/pleroma-fe#23
Co-authored-by: sfr <sol@solfisher.com>
Co-committed-by: sfr <sol@solfisher.com>
2022-06-27 16:15:24 +00:00
floatingghost 06343addef Merge pull request 'Render inline code correctly in MFM' (#21) from sfr/pleroma-fe:mfm-code into develop
Reviewed-on: AkkomaGang/pleroma-fe#21
2022-06-27 09:33:49 +00:00
Sol Fisher Romanoff eb69fc33f6
Render inline code correctly in MFM 2022-06-27 10:15:57 +03:00
floatingghost 9e13e5d164 Add cleaner message for rate-limited users (#19)
Reviewed-on: AkkomaGang/pleroma-fe#19
2022-06-26 19:02:49 +00:00
sfr 794906f01e Fix alt text wrap and line breaks (#14)
Reviewed-on: AkkomaGang/pleroma-fe#14
Co-authored-by: sfr <sol@solfisher.com>
Co-committed-by: sfr <sol@solfisher.com>
2022-06-26 18:36:04 +00:00
sfr 263ef17816 Use textarea instead of input for composing alt text (#15)
Reviewed-on: AkkomaGang/pleroma-fe#15
Co-authored-by: sfr <sol@solfisher.com>
Co-committed-by: sfr <sol@solfisher.com>
2022-06-26 17:51:13 +00:00
FloatingGhost 7025cb8bb0 Merge branch 'build-on-merge' into develop 2022-06-26 18:20:54 +01:00
FloatingGhost 821460075a also run build on push 2022-06-26 18:20:41 +01:00
floatingghost b87637c611 Merge pull request 'Build and release on merge into develop' (#17) from build-on-merge into develop
Reviewed-on: AkkomaGang/pleroma-fe#17
2022-06-26 17:14:52 +00:00
FloatingGhost e10588430f builds on merge into develop for ease of release 2022-06-26 18:13:57 +01:00
floatingghost dda1a2f75c Merge pull request 'Allow boosting own private posts' (#16) from sfr/pleroma-fe:boost-priv into develop
Reviewed-on: AkkomaGang/pleroma-fe#16
2022-06-26 17:11:08 +00:00
Yureka cc35202911
Allow boosting own private posts 2022-06-26 07:54:42 +03:00
floatingghost 9827c0e81e Merge pull request 'Remove auto-dismissing notifications' (#13) from sfr/pleroma-fe:develop into develop
Reviewed-on: AkkomaGang/pleroma-fe#13
2022-06-24 15:47:48 +00:00
Sol Fisher Romanoff f481cdd00b
Remove auto-dismissing notifications 2022-06-23 22:31:48 +03:00
floatingghost f0e180693e Merge pull request 'Don't show note textarea if logged out' (#12) from sfr/pleroma-fe:notes into develop
Reviewed-on: AkkomaGang/pleroma-fe#12
2022-06-23 19:09:57 +00:00
Sol Fisher Romanoff 9f9c5e01f1
Don't show note textarea if logged out 2022-06-23 20:02:47 +03:00
floatingghost c71405ccad Merge pull request 'Add private note field to user profile' (#9) from sfr/pleroma-fe:notes into develop
Reviewed-on: AkkomaGang/pleroma-fe#9
2022-06-23 14:33:18 +00:00
Sol Fisher Romanoff 231a4af754
Disable private note for self 2022-06-23 15:04:54 +03:00
Sol Fisher Romanoff 398b2624c8
Add note saving indicator 2022-06-23 15:04:19 +03:00
Sol Fisher Romanoff 4f0eabbd55
api: turn MASTODON_USER_URL into a function 2022-06-23 15:02:43 +03:00
Sol Fisher Romanoff fb2fc686b1
Add debounce to API request 2022-06-22 19:42:27 +03:00
Sol Fisher Romanoff 9923ff587b
Add private note field to user profile 2022-06-22 19:14:06 +03:00
FloatingGhost 261a9da374 remove parsing of sparkle 2022-06-22 11:26:48 +01:00
FloatingGhost ca8689fc88 bugfix: don't error if emoji not found 2022-06-20 14:55:38 +01:00
floatingghost 15ec862da0 Merge pull request 'lists' (#4) from sfr/pleroma-fe:lists into develop
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/4
2022-06-20 13:10:00 +00:00
Sol Fisher Romanoff ba4656312a
Add tests 2022-06-19 00:04:53 +03:00
Sol Fisher Romanoff a6136f6cb2
refactor: don't make API calls directly 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff 9217ca8476
Fetch all users in list before displaying 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff ab7001ed20
Use router for list timeline link 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff 023fcb506f
Lint fixes 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff a66d40e0e8
Clear list timeline on exit 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff a982af771b
Display list title 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff 92fac1cd9f
Allow removing accounts from list 2022-06-19 00:04:52 +03:00
Sol Fisher Romanoff dea803468f
Show already added accounts in search 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff d1af4bdd51
Fix account selection garbage 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff cf33b3295f
Add ability to edit and delete lists 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff bacb6c8fb3
Add list creation functionality 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff 3d18dd7e47
Make the list list page look good 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff d2c82a04d9
Add buttons to menus 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff 6e8c7460a2
Add lists listing page 2022-06-19 00:04:51 +03:00
Sol Fisher Romanoff e18e179a59
Fetch list of lists from the API 2022-06-19 00:04:50 +03:00
Sol Fisher Romanoff d5d464a289
Add list timeline rendering functionality
the list name is missing; this is because the API request to get it is different
to the API request for receiving the list timeline, and is not yet implemented.
2022-06-19 00:04:48 +03:00
floatingghost c1a8dc34da Merge pull request 'Add tests to #3' (#8) from sfr/pleroma-fe:develop into develop
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/8
2022-06-18 12:20:39 +00:00
Sol Fisher Romanoff cea08d41ee
Add tests to #3 2022-06-17 20:40:49 +03:00
floatingghost 3806f579b9 Merge pull request 'Correctly link to BE commit in version tab' (#3) from sfr/pleroma-fe:develop into develop
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/3
2022-06-17 11:56:12 +00:00
FloatingGhost 13048fce76 fix build 2022-06-17 12:23:19 +01:00
FloatingGhost a0ba907f6d build on push 2022-06-17 12:19:12 +01:00
FloatingGhost 35dfb09e6f force popover to be a bit bigger 2022-06-17 12:18:11 +01:00
floatingghost 8c9356b9fd Reuse the emoji picker for reactions (#7)
Fixes #6

Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/7
2022-06-16 11:41:08 +00:00
FloatingGhost 52644ec5cb remove IHBA ToS 2022-06-16 11:35:25 +01:00
floatingghost a0305e90f0 fix tests and add CI (#5)
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk>
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/5
2022-06-15 17:22:02 +00:00
FloatingGhost 1ad17fc2bf run stylelint 2022-06-15 16:58:02 +01:00
Sol Fisher Romanoff adc6b86e6b
Correctly link to BE commit in version tab 2022-06-14 22:13:51 +03:00
FloatingGhost 36309ebe04 don't clip on overflow 2022-06-14 17:28:41 +01:00
FloatingGhost 38d1074992 fix link display 2022-06-14 17:07:46 +01:00
FloatingGhost 9f764a4217 Merge branch 'mfm' into develop 2022-06-14 16:35:18 +01:00
FloatingGhost ef1c3d57b6 fix styling 2022-06-14 16:35:08 +01:00
FloatingGhost 3019dd4801 update gitignore 2022-06-14 15:57:20 +01:00
FloatingGhost ed42c476fb allow MFM authoring 2022-06-14 15:57:02 +01:00
floatingghost 0d85492d57 Merge pull request 'Link to akkoma repos in version tab' (#2) from sfr/pleroma-fe:develop into develop
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/2
2022-06-14 10:56:15 +00:00
Sol Fisher Romanoff dbf045c842
Link to akkoma repos in version tab 2022-06-14 13:52:11 +03:00
floatingghost f0b8468d45 Merge pull request 'i18n: change local posting notice' (#1) from sfr/pleroma-fe:develop into develop
Reviewed-on: http://akkoma.dev/AkkomaGang/pleroma-fe/pulls/1
2022-06-14 08:58:59 +00:00
Sol Fisher Romanoff c768641f09
i18n: change local posting notice 2022-06-14 11:55:29 +03:00
FloatingGhost 8f1aaf617a fix css 2022-06-12 14:13:04 +01:00
FloatingGhost a9f8ec5453 add custom emoji display 2022-06-12 14:11:07 +01:00
floatingghost c66a3e0206 Merge pull request 'Add emoji name as title tag' (#1) from sfr/pleroma-fe:develop into develop
Reviewed-on: https://git.ihatebeinga.live/IHBAGang/pleroma-fe/pulls/1
2022-06-09 13:45:24 +01:00
Sol Fisher Romanoff 58ca9b28fa
Add emoji name as title tag 2022-06-09 15:41:11 +03:00
sadposter d8a52f9cc4 fix width 2022-06-08 19:16:29 +01:00
FloatingGhost f6cf509a04 Merge remote-tracking branch 'upstream/develop' into develop 2022-06-08 18:09:16 +01:00
FloatingGhost a731f046b3 fix emoji sizing 2022-06-08 17:22:45 +01:00
FloatingGhost c65895b328 force width 2022-06-08 12:44:52 +01:00
FloatingGhost 3a1d6a1970 allow custom reactions 2022-06-08 12:37:22 +01:00
FloatingGhost 170a406cad allow customs 2022-06-08 02:40:20 +01:00
HJ 15229d27b4 Merge branch '3c-fixes' into 'develop'
restore notifications page, fix z-index issues

Closes #1166

See merge request pleroma/pleroma-fe!1534
2022-06-07 13:59:07 +00:00
Henry Jameson 9b5fe24ca4 restore notifications page, fix z-index issues 2022-06-07 16:52:03 +03:00
HJ 0aa334515b Merge branch 'threecolumn' into 'develop'
Layout refactoring + Three column mode

See merge request pleroma/pleroma-fe!1503
2022-05-31 17:46:59 +00:00
HJ 1418054b53 Merge branch 'from/develop/tusooa/fix-open-chat' into 'develop'
Fix Open Chat button

See merge request pleroma/pleroma-fe!1532
2022-05-31 17:46:31 +00:00
Henry Jameson a63aeccbcc force panel headers to be square on mobile (for now?) 2022-05-31 20:35:30 +03:00
Henry Jameson 58b8217283 fix gap between panel heading and timeline menu 2022-05-31 20:28:47 +03:00
Tusooa Zhu 152302cbff
Fix Open Chat button 2022-05-25 13:35:09 -04:00
Henry Jameson c3c120e91d fix? 2022-05-22 21:50:30 +03:00
Henry Jameson 1feff4dcc7 fix 2022-05-22 21:47:19 +03:00
HJ 48c739027c Merge branch 'from/develop/tusooa/lang-opts' into 'develop'
Fix registration error

See merge request pleroma/pleroma-fe!1527
2022-05-22 16:41:37 +00:00
HJ 68a2c5db98 Merge branch 'revert-3b6d72ef' into 'develop'
Revert "Merge branch 'revert-a88abc7e' into 'develop'"

See merge request pleroma/pleroma-fe!1528
2022-05-22 16:41:16 +00:00
HJ 9725443e60 Revert "Merge branch 'revert-a88abc7e' into 'develop'"
This reverts merge request !1526
2022-05-22 16:40:59 +00:00
HJ 3b6d72ef3b Merge branch 'revert-a88abc7e' into 'develop'
Revert "Merge branch 'from/develop/tusooa/lang-opts' into 'develop'"

See merge request pleroma/pleroma-fe!1526
2022-05-22 16:38:21 +00:00
HJ 069cf3fa87 Revert "Merge branch 'from/develop/tusooa/lang-opts' into 'develop'"
This reverts merge request !1494
2022-05-22 16:38:09 +00:00
Tusooa Zhu 79ee77a6fe
Fix registration error 2022-05-22 12:37:38 -04:00
HJ a88abc7ee3 Merge branch 'from/develop/tusooa/lang-opts' into 'develop'
Add language options

See merge request pleroma/pleroma-fe!1494
2022-05-22 16:35:51 +00:00
HJ 396349fdf2 Merge branch 'renovate/semver-5.x' into 'develop'
Update dependency semver to v5.7.1

See merge request pleroma/pleroma-fe!1491
2022-05-22 16:31:35 +00:00
HJ 62fcc16546 Merge branch 'renovate/webpack-merge-0.x' into 'develop'
Update dependency webpack-merge to v0.20.0

See merge request pleroma/pleroma-fe!1496
2022-05-22 16:29:39 +00:00
HJ dfc166c1ff Merge branch 'renovate/vuelidate-core-2.x' into 'develop'
Update dependency @vuelidate/core to v2.0.0-alpha.41

See merge request pleroma/pleroma-fe!1501
2022-05-22 16:28:24 +00:00
HJ 48f97ebf40 Merge branch 'eientei-pass-avatar-file-name' into 'develop'
Pass file name of cropped avatar to form data

See merge request pleroma/pleroma-fe!1522
2022-05-22 16:25:46 +00:00
HJ 3287ce9453 Merge branch 'from/develop/tusooa/poll-notif' into 'develop'
Poll-end notifications

See merge request pleroma/pleroma-fe!1524
2022-05-22 16:25:22 +00:00
Henry Jameson d137d5800a stick chat scroll to bottom to help with OSK resizing the viewport 2022-05-22 12:18:20 +03:00
Alexander Tumin 29b084b4b8 Pass file name of cropped avatar to form data 2022-05-21 19:44:44 +03:00
Tusooa Zhu 6e0ceda968
Add English translation for filtering end-of-poll notifications
Ref: poll-notif
2022-05-20 16:45:34 -04:00
Tusooa Zhu a35daceb5b
Add settings for filtering end-of-poll notifications
Ref: poll-notif
2022-05-20 16:45:33 -04:00
Tusooa Zhu a4b6a97b1b
Add English translations for poll-end notifications
Ref: poll-notif
2022-05-20 16:45:33 -04:00
Tusooa Zhu df487e3980
Show poll-end notifications
Ref: poll-notif
2022-05-20 16:45:33 -04:00
Henry Jameson 2c876f455a Merge remote-tracking branch 'origin/develop' into threecolumn
* origin/develop:
  Fix virtual scrolling when the user has a lot of pinned statuses
  fix "allow discovery" setting misbehaving
2022-05-20 12:45:06 +03:00
HJ c93adf2e9a Merge branch 'from/develop/tusooa/fix-vscroll-pinned' into 'develop'
Fix virtual scrolling when the user has a lot of pinned statuses

See merge request pleroma/pleroma-fe!1523
2022-05-20 09:44:35 +00:00
Tusooa Zhu 38ea47df89
Fix virtual scrolling when the user has a lot of pinned statuses 2022-05-19 20:42:40 -04:00
Henry Jameson c83657a072 stick chats to bottom 2022-05-20 00:28:34 +03:00
Henry Jameson a45a05fbb2 try out fully hidden input field 2022-05-16 23:46:32 +03:00
Henry Jameson 8d93e9c13c set/unset threecolumn mode on login/logout 2022-05-16 23:40:51 +03:00
Henry Jameson edbbbaad48 don't use wide mode for anon viewers 2022-05-09 23:25:41 +03:00
Henry Jameson ce8722b0e6 don't show "up to date" in user profile TL 2022-05-09 23:22:01 +03:00
Henry Jameson 54a40bfa01 fix inline conversation's shadow showing through outer header 2022-05-09 23:18:39 +03:00
Henry Jameson cc1e3c6792 fix incorrect sticking in user profile page 2022-05-09 23:14:58 +03:00
Henry Jameson fb70ea3b95 fix panel overlaps in firefox 2022-05-09 23:11:50 +03:00
Henry Jameson 4a956fa18d fix hidden input for file upload causing unintended scrolls 2022-05-09 23:07:55 +03:00
Pleroma Renovate Bot 45614b8804 Update dependency @vuelidate/core to v2.0.0-alpha.41 2022-05-02 09:06:51 +00:00
Tusooa Zhu f57171d7b9
Make lint happy 2022-04-29 20:36:56 -04:00
Tusooa Zhu 3633ea66d4
Make lint happy 2022-04-29 20:34:32 -04:00
Tusooa Zhu 093c85d006
Add English translation for language options 2022-04-29 20:34:32 -04:00
Tusooa Zhu 1d36ea5ec5
Add email language option to registration form 2022-04-29 20:34:32 -04:00
Tusooa Zhu d39de30221
Add config opts for email language 2022-04-29 20:34:31 -04:00
Tusooa Zhu a5e861cd01
Set userLanguage cookie when setting interface language 2022-04-29 20:34:29 -04:00
HJ 96a24ec625 Merge branch 'fix-discoverable-setting' into 'develop'
fix "allow discovery" setting misbehaving

See merge request pleroma/pleroma-fe!1518
2022-04-29 07:56:18 +00:00
Henry Jameson 91f833d1f0 fix "allow discovery" setting misbehaving 2022-04-29 10:52:16 +03:00
Henry Jameson 4d720974c3 minor fixes 2022-04-28 16:36:53 +03:00
Henry Jameson 23c5627639 sort and optimize panel.scss 2022-04-28 10:57:06 +03:00
Henry Jameson 5775abb25c fix panel footer colors 2022-04-28 10:52:41 +03:00
Henry Jameson e5be00dae1 fix mobile version 2022-04-26 18:55:21 +03:00
Henry Jameson cc84485650 improvements to chats view 2022-04-26 18:50:22 +03:00
Henry Jameson 4e4c96dfaf fix for notices being glued together 2022-04-26 18:15:12 +03:00
Henry Jameson f0f56bf148 more cleanup/fixes, gap b/w panels and topbar is closer to original now 2022-04-26 18:12:58 +03:00
Henry Jameson 49db16318b more fixes for shoutbox 2022-04-26 18:12:45 +03:00
Henry Jameson 079e289260 improvements and cleanup to input components 2022-04-26 17:31:26 +03:00
Henry Jameson a96367139c oops 2022-04-26 00:12:24 +03:00
Henry Jameson 1860bb354f make panel height property private since it relies on font size 2022-04-26 00:10:51 +03:00
Henry Jameson deece57584 better formatting 2022-04-26 00:10:33 +03:00
Henry Jameson 318c62c852 reduce height of post form by default 2022-04-26 00:08:55 +03:00
Henry Jameson 2a6f42fef3 unified how panel-footer works between regular timelines and user timeline 2022-04-25 23:50:22 +03:00
Henry Jameson f2b75a075d switching to center because baseline looks extremely off 2022-04-22 00:28:58 +03:00
Henry Jameson cd021bc6df cleanup & more fixes for alignments and sizing 2022-04-21 19:57:00 +03:00
Henry Jameson d4bd64a5f5 fix panel headers on mobile 2022-04-21 00:39:54 +03:00
Henry Jameson ed80ecfdbd cleanup 2022-04-21 00:27:48 +03:00
Henry Jameson 491449c418 undo mistake 2022-04-21 00:21:46 +03:00
Henry Jameson 33d92f9b16 relative units in line-height + some cleanup 2022-04-20 23:55:34 +03:00
Henry Jameson 7f513fe46f more em-sized fonts 2022-04-20 23:44:33 +03:00
Henry Jameson 58a975e8df cleanup and fixes 2022-04-20 23:22:51 +03:00
Henry Jameson 076c52788b fixes for mobile 2022-04-20 20:43:10 +03:00
Henry Jameson 80b1ccb267 restore old chat inputbox behavior 2022-04-20 20:40:10 +03:00
HJ 92b04ba7df Merge branch 'fix-chat-errors' into 'develop'
fix some chat errors/warnings that sometimes happen

See merge request pleroma/pleroma-fe!1515
2022-04-20 17:27:01 +00:00
Henry Jameson e388dbc168 Merge branch 'fix-chat-errors' into threecolumn
* fix-chat-errors:
  fix some chat errors/warnings that sometimes happen
  Fix incorrect close of a status popover when clicking Expand inside it
  fix tests
  fix hashtags by explicitly putting attributes
2022-04-20 20:23:34 +03:00
Henry Jameson 895eda3714 fix some chat errors/warnings that sometimes happen 2022-04-20 20:19:22 +03:00
Henry Jameson be8098e8ec fix chat 2022-04-20 20:16:41 +03:00
Henry Jameson 06f58f5349 i forgor 2022-04-20 20:03:18 +03:00
Henry Jameson 85c515b395 more fixes for timeline headers 2022-04-20 19:57:01 +03:00
Henry Jameson 631b8b93a4 tons of fixes mainly aimed at panel headings 2022-04-20 19:44:49 +03:00
HJ fb63e81ed1 Merge branch 'from/develop/tusooa/1157-popover-trigger' into 'develop'
Fix incorrect close of a status popover when clicking Expand inside it

Closes #1157

See merge request pleroma/pleroma-fe!1514
2022-04-20 09:15:18 +00:00
Tusooa Zhu a4ea0a30bf
Fix incorrect close of a status popover when clicking Expand inside it
basically Vue (3 in particular?) will make changes to DOM before this event
listener is called, and if the target is displayed using v-if, it will not
be part of the DOM at that time, and contains() will return false. so it
goes to call hidePopover() which caused this bug.
2022-04-19 20:24:24 -04:00
Henry Jameson aef6d52951 fix logoLeft not working at all 2022-04-20 01:25:30 +03:00
Henry Jameson d87a1fda59 fix scrollbars in dropdowns 2022-04-20 00:47:09 +03:00
Henry Jameson 9ae8ff0098 fix scrollbars in panel headers 2022-04-20 00:46:57 +03:00
Henry Jameson bb29218a6c fixate conversation heading 2022-04-19 23:06:57 +03:00
Henry Jameson b25c0c6f02 fix overflow that sometimes happens in sidebar due to too wide file
upload element
2022-04-19 22:22:16 +03:00
Henry Jameson 28556f7c27 localization updates 2022-04-12 22:01:04 +03:00
Henry Jameson 4b050c7fa5 properly ignore sticky elements when calculating offset because they
technically are following main scroll
2022-04-12 21:49:14 +03:00
Henry Jameson 3d37b9d8e1 unified layout-setting code and made an option to control or disable
third column behavior
2022-04-12 21:18:06 +03:00
HJ 1041a38f14 Merge branch 'fix-hashtags' into 'develop'
fix hashtags by explicitly putting attributes

See merge request pleroma/pleroma-fe!1513
2022-04-12 16:09:33 +00:00
Henry Jameson 0bb69d7fe0 fix tests 2022-04-12 19:04:32 +03:00
Henry Jameson d175e86901 fix hashtags by explicitly putting attributes 2022-04-12 18:10:19 +03:00
Henry Jameson b37932fdf4 fix main scrollbar on chrome 2022-04-12 17:27:34 +03:00
Henry Jameson 08ad2923a5 fix chats button alignment 2022-04-12 17:17:52 +03:00
Henry Jameson e5eca8a554 reduce chats jumpiness 2022-04-12 17:03:29 +03:00
Henry Jameson 0db756b4a5 fix post form/dropzone for good (?) 2022-04-12 01:22:31 +03:00
Henry Jameson f4447eb3a0 deal with browsers that don't support hiding scrollbars (somewhat) 2022-04-12 00:19:29 +03:00
Henry Jameson 2e10c1b0a3 enforce scroll to avoid jumpiness 2022-04-11 23:54:44 +03:00
Henry Jameson e744775ce8 fix dropdown menus 2022-04-11 23:49:46 +03:00
Henry Jameson 647b8e5f6b more fixes for z-indexes in panels 2022-04-11 23:34:56 +03:00
Henry Jameson 4f617a7293 fix for chat shadow 2022-04-11 23:30:41 +03:00
Henry Jameson df18a74adc fixes for z-indexes 2022-04-11 23:18:46 +03:00
Henry Jameson 2f1f1455aa fix notifications scrolling the main column 2022-04-11 16:45:16 +03:00
Henry Jameson e5f0f95356 fix dropzone 2022-04-11 00:20:27 +03:00
Henry Jameson 21f7cb39a8 cleanup 2022-04-10 22:50:33 +03:00
Henry Jameson 5d203e93ae improvements to relative panel sizing 2022-04-10 22:37:08 +03:00
Henry Jameson fe8b5b62ae fix chromium crashing on my machine :hyperjoy: LUL 2022-04-10 22:23:07 +03:00
Henry Jameson f27226b55c improvements to relative font sizes 2022-04-10 22:09:46 +03:00
Henry Jameson 666498e7b7 fix main post form having hidden emoji picker 2022-04-10 21:56:54 +03:00
Henry Jameson aa07b219c9 fix horizontal scroll, make hovered column render stuff on top of other
ones (popups, tooltips etc)
2022-04-10 21:32:29 +03:00
Henry Jameson 3f65c8b1d6 Merge remote-tracking branch 'origin/develop' into threecolumn
* origin/develop:
  Fix image cropper not closing correctly
2022-04-10 20:42:25 +03:00
Henry Jameson 62572c3204 remove margins from underlay since it causes horizontal scroll on
smaller screens
2022-04-10 20:41:36 +03:00
HJ c2a4051d72 Merge branch 'from/develop/tusooa/cropper-close' into 'develop'
Fix image cropper not closing correctly

See merge request pleroma/pleroma-fe!1512
2022-04-10 17:40:52 +00:00
Henry Jameson 3f9d9dd6bd underlay improvements 2022-04-10 20:27:09 +03:00
Henry Jameson 3e1b40ce29 fix new post button not working day1, minor stylistic fixes 2022-04-10 20:18:54 +03:00
Tusooa Zhu 169d13680a
Fix image cropper not closing correctly 2022-04-10 13:02:45 -04:00
Henry Jameson 0f28c28760 layout fixes 2022-04-10 19:29:10 +03:00
Henry Jameson d9f8091ce6 fix extra padding in thread view 2022-04-10 19:29:06 +03:00
Henry Jameson 5b664f464d chat fixes 2022-04-10 19:29:06 +03:00
Henry Jameson 7426417a52 more fixes 2022-04-10 18:44:22 +03:00
Henry Jameson a035fa4e6c fix timeline scroll-to-top 2022-04-10 18:44:03 +03:00
Henry Jameson 4c2301bc9f fix scrollable columns 2022-04-10 18:43:52 +03:00
Henry Jameson 77505fa7c9 revert layout back to scrollable body 2022-04-10 17:48:02 +03:00
Henry Jameson 2df48b1643 revert timeline changes 2022-04-10 17:47:54 +03:00
Henry Jameson ce9fd04865 Merge remote-tracking branch 'origin/develop' into threecolumn
* origin/develop:
  Fix tab switcher not working when some tabs hidden
  Fix mobile nav link text colour
  Fix shrug text in muted status
2022-04-10 14:54:03 +03:00
Henry Jameson 684650e14f restore margins for inline convos 2022-04-10 14:47:47 +03:00
Henry Jameson 0ff34f8a5a clean up and organize CSS, use ems for widths, use vars more 2022-04-10 14:23:30 +03:00
Henry Jameson 4750d9bb4c fix notifs' shadow peeking in when closed on mobile 2022-04-10 14:23:03 +03:00
HJ 4d15cbcbbd Merge branch 'from/develop/tusooa/1158-hidden-tabs' into 'develop'
Fix tab switcher not working when some tabs hidden

Closes #1158

See merge request pleroma/pleroma-fe!1511
2022-04-10 06:32:41 +00:00
Tusooa Zhu 3b02566e16
Fix tab switcher not working when some tabs hidden 2022-04-09 23:50:29 -04:00
Henry Jameson 5b47856329 fix scrollbars for real now 2022-04-08 13:34:20 +03:00
Henry Jameson 282e6812b3 fix chats, boost popover's z-index some more 2022-04-08 13:31:29 +03:00
Henry Jameson 6109fab14e cleanup, fix some things, try to disable scrollbars on mobile 2022-04-08 10:17:23 +03:00
HJ 87311cff09 Merge branch 'from/develop/tusooa/mobile-nav-link-col' into 'develop'
Fix mobile nav link text colour

See merge request pleroma/pleroma-fe!1510
2022-04-07 21:12:17 +00:00
Tusooa Zhu 6951fda0d6
Fix mobile nav link text colour 2022-04-07 15:59:03 -04:00
HJ 2d99cbc640 Merge branch 'from/develop/tusooa/1160-rm-shrug' into 'develop'
Fix shrug text in muted status

Closes #1160

See merge request pleroma/pleroma-fe!1509
2022-04-07 15:50:51 +00:00
Tusooa Zhu 22c70ae22a
Fix shrug text in muted status 2022-04-07 11:45:23 -04:00
Henry Jameson c71cf72eea fix mobile view 2022-04-07 16:39:39 +03:00
Henry Jameson 51c996bd7e boost z-index of popover 2022-04-07 16:18:39 +03:00
Henry Jameson 4007ddbf32 oops 2022-04-07 16:10:46 +03:00
Henry Jameson 6b67c095bf make scrollbars use button roundness 2022-04-07 16:07:47 +03:00
Henry Jameson b8b7ae8564 fancy scrollbars 2022-04-07 16:04:22 +03:00
Henry Jameson b5ded67c06 options to enable scrollbars and disable sticky headers 2022-04-07 15:11:23 +03:00
Henry Jameson d3d219f15d fix interactions page 2022-04-07 14:37:16 +03:00
Henry Jameson 8d623ab1ea fix some scroll issues 2022-04-07 11:36:14 +03:00
Henry Jameson ab7490e49b Merge remote-tracking branch 'origin/develop' into threecolumn
* origin/develop:
  Fix active popover style
  Use panel text instead of text for shoutbox icon
  Fix dropdown menu style inside panel header
  Fix phoenix sockets in dev mode
  Fix no reactivity on vuex 4 values
  fix tegulu
  heck
  fix i18n for good??
  force runtime build of i18n
  fix CSP by compiling the i18n templates as well
2022-04-07 10:33:20 +03:00
HJ d8324dd80b Merge branch 'from/develop/tusooa/shoutbox-icon-paneltext' into 'develop'
Use panel text instead of text for shoutbox icon

See merge request pleroma/pleroma-fe!1508
2022-04-07 07:24:40 +00:00
HJ caacaf238c Merge branch 'from/develop/tusooa/popover-in-panel-style' into 'develop'
Fix popover in panel header styling

See merge request pleroma/pleroma-fe!1507
2022-04-07 07:24:22 +00:00
HJ e4b8aaece6 Merge branch 'from/develop/tusooa/fix-shout-local' into 'develop'
Fix phoenix sockets in dev mode

See merge request pleroma/pleroma-fe!1506
2022-04-07 07:23:06 +00:00
HJ bfc7b6af8f Merge branch 'from/develop/tusooa/1156-vue3-shoutbox' into 'develop'
Fix no reactivity on vuex 4 values

Closes #1156

See merge request pleroma/pleroma-fe!1505
2022-04-07 07:01:09 +00:00
Tusooa Zhu fce9c5eeb2
Fix active popover style 2022-04-06 22:50:46 -04:00
Tusooa Zhu 6de87e8b65
Use panel text instead of text for shoutbox icon 2022-04-06 20:30:23 -04:00
Tusooa Zhu 041c72b07c
Fix dropdown menu style inside panel header 2022-04-06 20:14:17 -04:00
Tusooa Zhu 741a59e0cc
Fix phoenix sockets in dev mode
phoenix requires the Origin header to be set to the actual address,
so "http://localhost:xxxx" will not work.
2022-04-06 18:52:16 -04:00
Tusooa Zhu 4ddb6189dc
Fix no reactivity on vuex 4 values 2022-04-06 17:17:47 -04:00
HJ 0e56ac1c2b Merge branch 'fix-csp-vue3' into 'develop'
Makes develop usable on stock PleromaBE

See merge request pleroma/pleroma-fe!1504
2022-04-06 15:48:33 +00:00
Henry Jameson 853f5145be fix tegulu 2022-04-06 18:43:47 +03:00
Henry Jameson b213d25711 heck 2022-04-06 15:48:07 +03:00
Henry Jameson bd77f3a1a6 fix i18n for good?? 2022-04-06 15:45:44 +03:00
Henry Jameson 78817e37f7 force runtime build of i18n 2022-04-06 11:43:30 +03:00
Henry Jameson 2b0dd2cbae fix CSP by compiling the i18n templates as well 2022-04-05 23:45:26 +03:00
Henry Jameson 6a319154d9 teleport bread 2022-04-05 19:22:15 +03:00
Henry Jameson 4a068483ed wide mode initial implementation + cleanup 2022-04-05 18:38:05 +03:00
Henry Jameson 9e5037c715 make chatlist header sticky 2022-04-05 17:44:40 +03:00
Henry Jameson 835feea163 fix random error that sometimes occurs 2022-04-05 17:44:30 +03:00
Henry Jameson 52649bdabc cleanup & code splitting 2022-04-05 17:15:45 +03:00
Henry Jameson 0a606c2720 fix chat loading endlessly 2022-04-05 17:11:50 +03:00
Henry Jameson cfa8edf2c0 chats work and look a bit better 2022-04-05 13:19:12 +03:00
Henry Jameson e7ac0e5d68 fix main column having wild widths 2022-04-05 13:03:03 +03:00
Henry Jameson 71863061c6 fixed tons of stuff, at least it looks normalish on desktop 2022-04-04 19:41:09 +03:00
Henry Jameson 0e83ced25b refactored how main app layout works 2022-04-04 09:42:52 +03:00
HJ a613447105 Merge branch 'from/develop/tusooa/phoenix-1.6.2' into 'develop'
Fix phoenix at 1.6.2

See merge request pleroma/pleroma-fe!1502
2022-04-01 13:03:13 +00:00
Tusooa Zhu a3233e31d0
Fix phoenix at 1.6.2
According to https://github.com/phoenixframework/phoenix/issues/4623 ,
1.6.2 seems to not have the disconnection bug.
2022-04-01 08:44:18 -04:00
Pleroma Renovate Bot 8a55f21a98 Update dependency webpack-merge to v0.20.0 2022-04-01 09:08:00 +00:00
Pleroma Renovate Bot c7d8cff7b3 Update dependency semver to v5.7.1 2022-04-01 09:07:15 +00:00
HJ f71f101fce Merge branch 'vue3-again' into 'develop'
Migration to Vue 3 (again)

See merge request pleroma/pleroma-fe!1385
2022-03-31 17:45:29 +00:00
HJ afdc61b9b7 Merge branch 'vue3-no-compat' into 'vue3-again'
Remove Vue3 compat build

See merge request pleroma/pleroma-fe!1500
2022-03-31 17:39:08 +00:00
HJ 1d1ea7e703 Merge branch 'from/develop/tusooa/fix-feat-shoutbox-en' into 'develop'
Fix English translation of Shoutbox in features panel

See merge request pleroma/pleroma-fe!1489
2022-03-30 21:40:19 +00:00
Henry Jameson 052ad2fe3f Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  oops
2022-03-30 23:54:21 +03:00
Henry Jameson a0099ecb66 oops 2022-03-30 23:54:11 +03:00
Henry Jameson 9940739f1f Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  fix some mishaps i noticed during self-review
2022-03-30 23:52:24 +03:00
Henry Jameson afbe1a96ac fix some mishaps i noticed during self-review 2022-03-30 23:48:06 +03:00
Henry Jameson e029c2864f Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  fix importer
2022-03-30 18:00:48 +03:00
Henry Jameson dadf2f407f fix importer 2022-03-30 18:00:37 +03:00
Henry Jameson 6751c22a23 Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  make all clickable icons into actual buttons
2022-03-30 13:13:41 +03:00
Henry Jameson 1943991077 make all clickable icons into actual buttons 2022-03-30 12:34:27 +03:00
Henry Jameson 115170f35d Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  fix emoji input warning spam
  fix error clear icon
  Add controlledShowingLongSubject and toggle in StatusContent props
2022-03-30 01:26:35 +03:00
Henry Jameson c3690b456e fix emoji input warning spam 2022-03-30 01:24:53 +03:00
Henry Jameson 70593e71e6 fix error clear icon 2022-03-30 01:24:17 +03:00
HJ 1c60609547 Merge branch 'vue3-again' into 'vue3-again'
Add controlledShowingLongSubject and toggle in StatusContent props

See merge request pleroma/pleroma-fe!1499
2022-03-29 18:13:27 +00:00
Tusooa Zhu b84acfd7b7
Add controlledShowingLongSubject and toggle in StatusContent props 2022-03-29 13:56:42 -04:00
Henry Jameson 97e072d93a how did this get back?? 2022-03-29 20:23:44 +03:00
Henry Jameson 2179054384 Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  fix warning about custom component
  fix?
  fix some issues with trees
  removing uselsess stuff
  fix reset buttons in profile again
  fix spacing in poll expiration label
  registration fixes
2022-03-29 20:00:59 +03:00
Henry Jameson a3f48fc3f4 fix warning about custom component 2022-03-29 19:55:30 +03:00
Henry Jameson de2f968645 fix? 2022-03-29 19:44:07 +03:00
Henry Jameson e1483488c7 fix some issues with trees 2022-03-29 19:23:30 +03:00
Henry Jameson a1822f073d removing uselsess stuff 2022-03-29 19:21:13 +03:00
Henry Jameson 218b15b5fd fix reset buttons in profile again 2022-03-29 19:12:57 +03:00
Henry Jameson bc029b0fa2 fix spacing in poll expiration label 2022-03-29 19:04:01 +03:00
Henry Jameson 2d7f242713 remove unused props to fix test 2022-03-29 16:33:34 +03:00
Henry Jameson 0afc955ebd registration fixes 2022-03-29 16:08:57 +03:00
Henry Jameson e80e53d9d2 Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  re-fix i18n warnings again
  fix qr code
2022-03-29 16:00:56 +03:00
Henry Jameson afcfcce2e6 re-fix i18n warnings again 2022-03-29 15:46:21 +03:00
Henry Jameson 3171241c6f fix qr code 2022-03-29 15:44:42 +03:00
Henry Jameson 3e0bb91ff2 Merge branch 'vue3-again' into vue3-no-compat
* vue3-again:
  lint + fixes for registration
  fix production build's reply not working in tree mode
  lock down version?
  manual lint
  Revert "fix weird thing i somehow missed"
  Revert "lint"
  fix weird thing i somehow missed
  lint
2022-03-29 15:35:47 +03:00
Henry Jameson 5bbc0e0bb5 lint + fixes for registration 2022-03-29 15:35:18 +03:00
Henry Jameson 3799983d4f fix production build's reply not working in tree mode 2022-03-29 12:43:42 +03:00
Henry Jameson 3f04ebd89a lock down version? 2022-03-29 12:27:59 +03:00
Henry Jameson b93e5437bd manual lint 2022-03-29 12:04:09 +03:00
Henry Jameson 64d56e6515 Revert "fix weird thing i somehow missed"
This reverts commit b132581b3a.
2022-03-29 11:59:00 +03:00
Henry Jameson d9d4d8954e Revert "lint"
This reverts commit f20ae34400.
2022-03-29 11:57:54 +03:00
Henry Jameson b132581b3a fix weird thing i somehow missed 2022-03-29 11:47:22 +03:00
Henry Jameson f20ae34400 lint 2022-03-29 01:04:37 +03:00
Henry Jameson dc8bef7928 remove compat build 2022-03-29 00:58:17 +03:00
Henry Jameson 650e69c336 fix misc warnings 2022-03-29 00:02:02 +03:00
Henry Jameson f21dc21a83 properly implement resettableAsyncComponent 2022-03-28 23:55:57 +03:00
Henry Jameson 9afbb12f95 fix opacity control again 2022-03-28 23:55:11 +03:00
Henry Jameson 7b10e47b21 rename some binding hooks according to new names 2022-03-28 23:54:30 +03:00
Henry Jameson 4b630c3c36 fix warnings 2022-03-28 17:37:26 +03:00
Henry Jameson bdd240a230 fix some more warnings 2022-03-28 17:21:42 +03:00
Henry Jameson c57af7e242 remove some warnings 2022-03-28 17:13:48 +03:00
Henry Jameson f706234d77 fix being unable to set/reset background (and possibly avatar/banner) 2022-03-28 15:01:34 +03:00
Henry Jameson 805615d52b fix background not showing 2022-03-28 14:26:50 +03:00
Henry Jameson 8424b772b0 fix tabs in search 2022-03-27 14:43:16 +03:00
Henry Jameson 115f38c422 fix optional color inputs 2022-03-27 14:20:55 +03:00
Henry Jameson 48fd8a66ad fix opacity control 2022-03-27 14:18:02 +03:00
Henry Jameson 53cde52027 fix font control 2022-03-27 14:16:23 +03:00
Henry Jameson 75f6506bc7 fix (You) spacing 2022-03-27 14:10:45 +03:00
Henry Jameson 1d77063a4b fix shadow control in theme tab 2022-03-27 13:45:02 +03:00
Henry Jameson ccd7378347 fix (roundness) ranges in theme tab 2022-03-27 13:31:56 +03:00
Henry Jameson 8e711e0587 get rid of portal-vue 2022-03-27 12:59:15 +03:00
Henry Jameson 87d420a92b port !1488 to vue3 2022-03-27 12:58:28 +03:00
Henry Jameson d6bbccdd71 Merge remote-tracking branch 'origin/develop' into vue3-again
* origin/develop:
  Remove debugging code
  Fix overlapping buttons in Theme settings
  Update dependency ruffle-mirror to v2021.12.31
  Update dependency babel-loader to v8.2.4
2022-03-27 12:50:00 +03:00
Henry Jameson 913749739f fix user-list-popover 2022-03-27 12:29:28 +03:00
Henry Jameson 0b7a8dca15 fix duplicate setting (most likely a merge issue) 2022-03-27 12:26:51 +03:00
Henry Jameson dd4672dc9a fix opening directly to filtering tab not working 2022-03-27 12:24:38 +03:00
Henry Jameson 9ac7046521 Fix notices not disappearing on their own 2022-03-27 12:21:33 +03:00
Henry Jameson e4c804fac0 fix another spacing issue 2022-03-27 12:03:31 +03:00
HJ fd77c583bf Merge branch 'from/develop/tusooa/fix-overlap-button' into 'develop'
Fix overlapping buttons in Theme settings

See merge request pleroma/pleroma-fe!1488
2022-03-25 13:22:06 +00:00
HJ b319c0c72b Remove debugging code 2022-03-25 13:17:22 +00:00
Tusooa Zhu c5551e834b
Fix English translation of Shoutbox in features panel 2022-03-24 19:28:15 -04:00
Tusooa Zhu e58422889b
Fix overlapping buttons in Theme settings 2022-03-24 18:03:13 -04:00
Henry Jameson b7755314b1 fix forms closing in timelines 2022-03-24 14:09:25 +02:00
Henry Jameson 3fb647b34b fix minor renames 2022-03-24 13:50:22 +02:00
Henry Jameson 0eb9c019e4 woah ima stupid 2022-03-24 13:41:52 +02:00
HJ aa0b2e0723 Merge branch 'renovate/ruffle-mirror-2021.x' into 'develop'
Update dependency ruffle-mirror to v2021.12.31

See merge request pleroma/pleroma-fe!1486
2022-03-24 10:10:03 +00:00
Henry Jameson 4539feed40 fix checkboxes, specifically the NSFW one 2022-03-24 11:41:39 +02:00
Pleroma Renovate Bot 20c14a1d99 Update dependency ruffle-mirror to v2021.12.31 2022-03-24 09:05:00 +00:00
Henry Jameson 9793002070 cleanup console log 2022-03-23 16:53:57 +02:00
Henry Jameson 01d8fa4e54 fix i18n at places 2022-03-23 16:32:53 +02:00
Henry Jameson 961ca3a71b fix all the spacings i could find 2022-03-23 16:15:05 +02:00
Henry Jameson 08811e5a27 fix spacings in notifications 2022-03-23 16:08:45 +02:00
Henry Jameson a6fae395da fix dupe id 2022-03-23 16:05:53 +02:00
Henry Jameson d690b88c1c fix animations 2022-03-23 15:53:36 +02:00
Henry Jameson 322ec8681a cleanup 2022-03-23 15:44:37 +02:00
HJ e1bfa6fbd3 Merge branch 'renovate/babel-monorepo' into 'develop'
Update dependency babel-loader to v8.2.4

See merge request pleroma/pleroma-fe!1484
2022-03-23 13:04:33 +00:00
Pleroma Renovate Bot db0e1a2534 Update dependency babel-loader to v8.2.4 2022-03-23 09:05:04 +00:00
Henry Jameson d524e98348 fix capitalization (and localization of tooltips for scope icon) 2022-03-22 20:42:29 +02:00
Henry Jameson 7afa6c9f40 listeners aren't actually used 2022-03-22 20:22:28 +02:00
Henry Jameson 538903f9d8 fix selects in settings screen 2022-03-22 20:17:25 +02:00
Henry Jameson c5a6f40dff fix tabs not being able to be "disabled" 2022-03-22 20:15:21 +02:00
Henry Jameson b817e09ee8 fix avatars not opening inline card 2022-03-22 19:43:11 +02:00
Henry Jameson 6b5791fda6 fix other weird route 2022-03-22 19:20:12 +02:00
Henry Jameson 3250e59266 fix routes test 2022-03-22 18:56:54 +02:00
Henry Jameson e5ae0671ce skip user profile test for now https://github.com/vuejs/test-utils/issues/1382 2022-03-22 18:56:39 +02:00
Henry Jameson 9d7a7e2019 fix emoji input tests 2022-03-22 18:22:23 +02:00
Henry Jameson c2cf13fc00 fix richcontent and its tests 2022-03-22 18:22:23 +02:00
Henry Jameson c3546ea856 fix tests running 2022-03-22 18:22:23 +02:00
Henry Jameson edb66ecade fix mobile post button being too square 2022-03-22 16:39:27 +02:00
Henry Jameson c6a4a0a320 Merge remote-tracking branch 'origin/develop' into vue3-again
* origin/develop:
  quick fix for alignment in avatars, juggling multiple branches is confusing
  fix even more issues with avatars
  Update dependency ora to v0.4.1
  Update dependency mini-css-extract-plugin to v0.12.0
  Update dependency karma-firefox-launcher to v1.3.0
  fix avatars in mobile view
2022-03-22 12:14:02 +02:00
HJ 6a31962ca0 Merge branch 'fix-avatars3' into 'develop'
quick fix for alignment in avatars

See merge request pleroma/pleroma-fe!1483
2022-03-22 10:03:17 +00:00
Henry Jameson fa99abf106 quick fix for alignment in avatars, juggling multiple branches is confusing 2022-03-22 11:57:21 +02:00
HJ 9be06d9f71 Merge branch 'renovate/mini-css-extract-plugin-0.x' into 'develop'
Update dependency mini-css-extract-plugin to v0.12.0

See merge request pleroma/pleroma-fe!1480
2022-03-22 09:54:23 +00:00
HJ 966919874e Merge branch 'fix-avatars2' into 'develop'
fix even more issues with avatars

See merge request pleroma/pleroma-fe!1482
2022-03-22 09:53:13 +00:00
HJ a253c95170 Merge branch 'develop' into 'fix-avatars2'
# Conflicts:
#   src/components/status/status.scss
2022-03-22 09:47:24 +00:00
Henry Jameson c6e0dcf08e fix even more issues with avatars 2022-03-22 11:43:51 +02:00
HJ 0147226b3d Merge branch 'renovate/ora-0.x' into 'develop'
Update dependency ora to v0.4.1

See merge request pleroma/pleroma-fe!1481
2022-03-22 09:20:54 +00:00
HJ 1571053fba Merge branch 'renovate/karma-firefox-launcher-1.x' into 'develop'
Update dependency karma-firefox-launcher to v1.3.0

See merge request pleroma/pleroma-fe!1475
2022-03-22 09:20:11 +00:00
Pleroma Renovate Bot 623aa3d20d Update dependency ora to v0.4.1 2022-03-22 09:06:15 +00:00
Pleroma Renovate Bot 636a55e72d Update dependency mini-css-extract-plugin to v0.12.0 2022-03-22 09:06:08 +00:00
Pleroma Renovate Bot 304f871332 Update dependency karma-firefox-launcher to v1.3.0 2022-03-22 09:06:00 +00:00
HJ 2cd8a3ec8d Merge branch 'fix-mobile-avatars' into 'develop'
fix avatars in mobile view

See merge request pleroma/pleroma-fe!1479
2022-03-22 08:24:42 +00:00
Henry Jameson 971cec024c fix avatars in mobile view 2022-03-22 10:20:45 +02:00
Henry Jameson 7a17eb7fec fix selects 2022-03-21 22:01:08 +02:00
Henry Jameson 4cb14c257c fix expert mode checkbox not working 2022-03-21 21:34:55 +02:00
Henry Jameson 1187727b60 fix tabswitcher bugs 2022-03-21 21:29:51 +02:00
Henry Jameson 54fd7e2be6 Merge remote-tracking branch 'origin/develop' into vue3-again
* origin/develop:
  improve the looks of bot indicator
  fix bot indicator appearing on retweeter avatar
  Update dependency localforage to v1.10.0
  Update dependency http-proxy-middleware to v0.21.0
  Update dependency eslint-plugin-standard to v4.1.0
  Update dependency eslint-plugin-import to v2.25.4
  Update babel monorepo to v7.17.8
  Update dependency iso-639-1 to v2.1.13
  Update dependency express to v4.17.3
  Update dependency eslint-plugin-promise to v4.3.1
  Update dependency eslint-loader to v2.2.1
2022-03-21 21:09:48 +02:00
HJ 0ef58696bf Merge branch 'bot-indicator-fixes' into 'develop'
Bot indicator fixes

See merge request pleroma/pleroma-fe!1477
2022-03-21 19:04:21 +00:00
Henry Jameson 9478a462a7 improve the looks of bot indicator 2022-03-21 20:59:25 +02:00
Henry Jameson 4e2fd7baf9 fix bot indicator appearing on retweeter avatar 2022-03-21 20:39:56 +02:00
HJ 66fb3987d6 Merge branch 'renovate/localforage-1.x' into 'develop'
Update dependency localforage to v1.10.0

See merge request pleroma/pleroma-fe!1476
2022-03-21 18:27:24 +00:00
HJ 1e60a491c4 Merge branch 'renovate/eslint-plugin-standard-4.x' into 'develop'
Update dependency eslint-plugin-standard to v4.1.0

See merge request pleroma/pleroma-fe!1471
2022-03-21 18:26:27 +00:00
HJ 12ce58a5a0 Merge branch 'renovate/babel-monorepo' into 'develop'
Update babel monorepo to v7.17.8

See merge request pleroma/pleroma-fe!1469
2022-03-21 18:25:29 +00:00
HJ 2f24f3312d Merge branch 'renovate/http-proxy-middleware-0.x' into 'develop'
Update dependency http-proxy-middleware to v0.21.0

See merge request pleroma/pleroma-fe!1473
2022-03-21 18:24:02 +00:00
HJ 1cc35b6df8 Merge branch 'renovate/eslint-plugin-import-2.x' into 'develop'
Update dependency eslint-plugin-import to v2.25.4

See merge request pleroma/pleroma-fe!1468
2022-03-21 18:19:24 +00:00
Pleroma Renovate Bot 4f2be206df Update dependency localforage to v1.10.0 2022-03-21 18:16:34 +00:00
Pleroma Renovate Bot 6074ad67ab Update dependency http-proxy-middleware to v0.21.0 2022-03-21 18:16:06 +00:00
Pleroma Renovate Bot c5cb76ac3b Update dependency eslint-plugin-standard to v4.1.0 2022-03-21 18:15:53 +00:00
Pleroma Renovate Bot e4b010321d Update dependency eslint-plugin-import to v2.25.4 2022-03-21 18:15:39 +00:00
Pleroma Renovate Bot 5e4ff5de7c Update babel monorepo to v7.17.8 2022-03-21 18:15:22 +00:00
HJ 6b14b645be Merge branch 'renovate/eslint-loader-2.x' into 'develop'
Update dependency eslint-loader to v2.2.1

See merge request pleroma/pleroma-fe!1467
2022-03-21 18:13:00 +00:00
HJ 79258f61be Merge branch 'renovate/eslint-plugin-promise-4.x' into 'develop'
Update dependency eslint-plugin-promise to v4.3.1

See merge request pleroma/pleroma-fe!1470
2022-03-21 18:10:10 +00:00
HJ 3ea442667f Merge branch 'renovate/express-4.x' into 'develop'
Update dependency express to v4.17.3

See merge request pleroma/pleroma-fe!1472
2022-03-21 18:05:16 +00:00
HJ 6c120cc576 Merge branch 'renovate/iso-639-1-2.x' into 'develop'
Update dependency iso-639-1 to v2.1.13

See merge request pleroma/pleroma-fe!1474
2022-03-21 18:01:48 +00:00
Pleroma Renovate Bot 89d6e624f2 Update dependency iso-639-1 to v2.1.13 2022-03-21 09:07:38 +00:00
Pleroma Renovate Bot 060aa41f35 Update dependency express to v4.17.3 2022-03-20 09:05:19 +00:00
Pleroma Renovate Bot 67f5cf3c03 Update dependency eslint-plugin-promise to v4.3.1 2022-03-19 09:07:04 +00:00
Henry Jameson 5948d20f00 mutes and blocks tab works 2022-03-18 13:36:08 +02:00
Henry Jameson b3ed29ff02 made withLoadMore work... sorta 2022-03-18 13:32:36 +02:00
Pleroma Renovate Bot 5d973df5bd Update dependency eslint-loader to v2.2.1 2022-03-18 09:04:52 +00:00
Henry Jameson 26bfbdc2ad fix sw compilation 2022-03-18 11:02:00 +02:00
Henry Jameson 50ea6dd142 Merge remote-tracking branch 'origin/develop' into vue3-again
* origin/develop:
  Update dependency cropperjs to v1.5.12
  Update dependency body-scroll-lock to v2.7.1
  Update babel monorepo
2022-03-18 10:59:28 +02:00
HJ 6f1d953642 Merge branch 'renovate/cropperjs-1.x' into 'develop'
Update dependency cropperjs to v1.5.12

See merge request pleroma/pleroma-fe!1465
2022-03-18 08:58:03 +00:00
HJ 86f1b88d79 Merge branch 'renovate/body-scroll-lock-2.x' into 'develop'
Update dependency body-scroll-lock to v2.7.1

See merge request pleroma/pleroma-fe!1464
2022-03-18 08:57:08 +00:00
HJ 4610b6e547 Merge branch 'renovate/babel-monorepo' into 'develop'
Update babel monorepo

See merge request pleroma/pleroma-fe!1462
2022-03-17 09:11:07 +00:00
Pleroma Renovate Bot be02516776 Update dependency cropperjs to v1.5.12 2022-03-17 09:05:41 +00:00
Pleroma Renovate Bot 4e100b9ea2 Update dependency body-scroll-lock to v2.7.1 2022-03-17 09:05:34 +00:00
Pleroma Renovate Bot 8ae1f7e192 Update babel monorepo 2022-03-17 09:05:20 +00:00
Henry Jameson fea0c91f74 bunp node version 2022-03-17 09:33:36 +02:00
Henry Jameson 051d51bcd9 fix suggest not working 2022-03-17 09:28:19 +02:00
Henry Jameson 5718c6491e fix selects being messed up 2022-03-17 09:06:05 +02:00
Henry Jameson a97c07bfdf fix settings not persisting 2022-03-17 09:02:26 +02:00
Henry Jameson d815f984fb fix i18n errors related to @ symbol 2022-03-17 08:53:45 +02:00
Henry Jameson 4993dc37e2 fix rich content not rendering stillimage nor links correctly 2022-03-17 08:53:45 +02:00
Henry Jameson 0671aa0dd0 fix tabswitcher 2022-03-17 08:53:45 +02:00
Henry Jameson b62653c202 fix chat user titles 2022-03-17 08:37:01 +02:00
Henry Jameson be4244acde fix some warnings 2022-03-17 08:35:19 +02:00
Henry Jameson 8311d4deba shit renders yo 2022-03-16 22:13:21 +02:00
Henry Jameson e51144809f shit boots yo 2022-03-16 22:02:44 +02:00
Henry Jameson cd4ad2df11 Merge remote-tracking branch 'origin/develop' into vue3-again
* origin/develop: (475 commits)
  Apply 1 suggestion(s) to 1 file(s)
  Update dependency @ungap/event-target to v0.2.3
  Update package.json
  fix broken icons after FA upgrade
  Update Font Awesome
  Update dependency webpack-dev-middleware to v3.7.3
  Update dependency vuelidate to v0.7.7
  Pin dependency @kazvmoe-infra/pinch-zoom-element to 1.2.0
  lint
  Make media modal buttons larger
  Add English translation for hide tooltip
  Add hide button to media modal
  Lint
  Prevent hiding media viewer if swiped over SwipeClick
  Fix webkit image blurs
  Fix video in media modal not displaying properly
  Add changelog for https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1403
  Remove image box-shadow in media modal
  Clean up debug code for image pinch zoom
  Bump @kazvmoe-infra/pinch-zoom-element to 1.2.0 on npm
  ...
2022-03-16 21:00:20 +02:00
HJ b632d740c1 Merge branch 'expert-settings-and-serverside' into 'develop'
Expert settings and serverside settings + new defaults

See merge request pleroma/pleroma-fe!1438
2022-03-16 17:33:24 +00:00
HJ 123de8aad0 Apply 1 suggestion(s) to 1 file(s) 2022-03-16 17:02:09 +00:00
HJ 186078ae2a Merge branch 'renovate/ungap-event-target-0.x' into 'develop'
Update dependency @ungap/event-target to v0.2.3

See merge request pleroma/pleroma-fe!1463
2022-03-16 09:15:24 +00:00
Pleroma Renovate Bot 23c80794d5 Update dependency @ungap/event-target to v0.2.3 2022-03-16 09:05:13 +00:00
HJ 3e1415ef89 Merge branch 'hj-develop-patch-28607' into 'develop'
Fix build due to github shenanigans

See merge request pleroma/pleroma-fe!1461
2022-03-15 19:07:02 +00:00
HJ 2439f55342 Merge branch 'renovate/font-awesome' into 'develop'
Update Font Awesome

See merge request pleroma/pleroma-fe!1460
2022-03-15 19:03:44 +00:00
HJ b0babee98a Update package.json 2022-03-15 19:02:34 +00:00
Henry Jameson 47bb08514b fix broken icons after FA upgrade 2022-03-15 21:00:52 +02:00
HJ 60eb164bdc Merge branch 'renovate/webpack-dev-middleware-3.x' into 'develop'
Update dependency webpack-dev-middleware to v3.7.3

See merge request pleroma/pleroma-fe!1459
2022-03-15 18:40:58 +00:00
Pleroma Renovate Bot 3101456a85 Update Font Awesome 2022-03-15 09:05:20 +00:00
Pleroma Renovate Bot 5e851e643b Update dependency webpack-dev-middleware to v3.7.3 2022-03-15 09:05:08 +00:00
HJ bfa62db274 Merge branch 'renovate/pin-dependencies' into 'develop'
Pin dependency @kazvmoe-infra/pinch-zoom-element to 1.2.0

See merge request pleroma/pleroma-fe!1457
2022-03-15 08:22:33 +00:00
HJ b349bcd427 Merge branch 'renovate/vuelidate-0.x' into 'develop'
Update dependency vuelidate to v0.7.7

See merge request pleroma/pleroma-fe!1458
2022-03-14 09:11:28 +00:00
Pleroma Renovate Bot 7e6e6292f8 Update dependency vuelidate to v0.7.7 2022-03-14 09:05:17 +00:00
Pleroma Renovate Bot 34592fa63a Pin dependency @kazvmoe-infra/pinch-zoom-element to 1.2.0 2022-03-14 09:05:10 +00:00
Henry Jameson 71c0b59866 lint 2022-03-14 09:35:29 +02:00
Henry Jameson a97db1efd6 Merge remote-tracking branch 'origin/develop' into expert-settings-and-serverside
* origin/develop: (83 commits)
  Make media modal buttons larger
  Add English translation for hide tooltip
  Add hide button to media modal
  Lint
  Prevent hiding media viewer if swiped over SwipeClick
  Fix webkit image blurs
  Fix video in media modal not displaying properly
  Add changelog for https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1403
  Remove image box-shadow in media modal
  Clean up debug code for image pinch zoom
  Bump @kazvmoe-infra/pinch-zoom-element to 1.2.0 on npm
  Bump pinch-zoom-element version
  Clean up
  Check whether we swiped only for mouse pointer
  Scale swipe threshold with viewport width
  Update pinch-zoom-element
  Allow pinch-zoom to fill the whole screen
  Use native click for hiding overlay
  Reset position on swipe end even if we cannot navigate
  Make lint happy
  ...
2022-03-14 09:31:24 +02:00
HJ e34d71fc1f Merge branch 'from/develop/tusooa/tree-threading' into 'develop'
Add the option to display threads as trees

See merge request pleroma/pleroma-fe!1407
2022-03-13 17:31:46 +00:00
HJ 89efb0d2f4 Merge branch 'from/develop/tusooa/media-touch-actions' into 'develop'
Be able to scroll and pan media in media modal

See merge request pleroma/pleroma-fe!1403
2022-03-13 17:22:30 +00:00
Tusooa Zhu 1b204012ea
Make media modal buttons larger 2022-03-13 12:02:03 -04:00
Tusooa Zhu b67a557a8c
Add English translation for hide tooltip 2022-03-13 12:02:03 -04:00
Tusooa Zhu 5fb302d0f1
Add hide button to media modal 2022-03-13 12:02:02 -04:00
Tusooa Zhu 7e21853cca
Lint 2022-03-13 12:02:02 -04:00
Tusooa Zhu 7dd1a0dd30
Prevent hiding media viewer if swiped over SwipeClick 2022-03-13 12:02:02 -04:00
Tusooa Zhu 90b066a744
Fix webkit image blurs 2022-03-13 12:02:02 -04:00
Tusooa Zhu 1128cc463c
Fix video in media modal not displaying properly 2022-03-13 12:02:02 -04:00
Tusooa Zhu 22d8961c5e
Add changelog for https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1403 2022-03-13 12:02:02 -04:00
Tusooa Zhu 76727cd39c
Remove image box-shadow in media modal
The box-shadow causes an image to be very blurry on Webkit browsers
(experienced: Konqueror, Safari; heard of: Chrome) when scaled up
if the initial size of the image is much smaller than the actual size
(e.g. when viewing a very long picture).

The shadow is not really obvious anyway.
2022-03-13 12:02:02 -04:00
Tusooa Zhu 5829cd98af
Clean up debug code for image pinch zoom 2022-03-13 12:02:02 -04:00
Tusooa Zhu 49fa9c47e9
Bump @kazvmoe-infra/pinch-zoom-element to 1.2.0 on npm
https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1403
2022-03-13 12:02:00 -04:00
Tusooa Zhu 495960c83a
Bump pinch-zoom-element version 2022-03-13 12:00:45 -04:00
Tusooa Zhu 3b4afdf567
Clean up 2022-03-13 12:00:45 -04:00
Tusooa Zhu a485ebc2bb
Check whether we swiped only for mouse pointer 2022-03-13 12:00:45 -04:00
Tusooa Zhu 6980e4ddf1
Scale swipe threshold with viewport width 2022-03-13 12:00:44 -04:00
Tusooa Zhu cb19db1006
Update pinch-zoom-element 2022-03-13 12:00:44 -04:00
Tusooa Zhu ddf6c9cef0
Allow pinch-zoom to fill the whole screen 2022-03-13 12:00:44 -04:00
Tusooa Zhu 9f3a983fef
Use native click for hiding overlay
The pointerup strategy is unsuccessful, as some other overlays
(Firefox's Inspect Element) will pass down pointerup events.
2022-03-13 12:00:44 -04:00
Tusooa Zhu 839627ffc4
Reset position on swipe end even if we cannot navigate 2022-03-13 12:00:44 -04:00
Tusooa Zhu f3269cdc10
Make lint happy 2022-03-13 12:00:44 -04:00
Tusooa Zhu 3502d374e3
Prevent the click event from firing on content below modal 2022-03-13 12:00:44 -04:00
Tusooa Zhu 0190a36070
Add missing swipe click component 2022-03-13 12:00:44 -04:00
Tusooa Zhu 23a6b86ef3
Clean up 2022-03-13 12:00:44 -04:00
Tusooa Zhu 29cd8fbd3b
Add swipe-click handler to media modal
Now swiping will correctly change the current media, and with a good
preview. Clicking without swiping closes the overlay.
2022-03-13 12:00:44 -04:00
Tusooa Zhu a36673a6a8
Use pinch-zoom-element for pinch zoom functionality 2022-03-13 12:00:41 -04:00
Tusooa Zhu 544db06294
Add pan threshold 2022-03-13 11:56:35 -04:00
Tusooa Zhu d9030b4fdd
Handle pinch action 2022-03-13 11:56:35 -04:00
Tusooa Zhu a7570f5eb2
Preview swipe action 2022-03-13 11:56:34 -04:00
Tusooa Zhu f96e5882d1
Make media modal be aware of multi-touch actions
Originally the media viewer would think every touch is a swipe (one-finger
touch event), so we would encounter the case where a two-finger scale event
would incorrectly change the current media. This is now fixed.
2022-03-13 11:56:30 -04:00
Henry Jameson f16f35a4d4 Merge remote-tracking branch 'origin/develop' into expert-settings-and-serverside
* origin/develop:
  Update dependency v-click-outside to v2.1.5
  Update dependency shelljs to v0.8.5
  Update dependency portal-vue to v2.1.7
  Update dependency lodash to v4.17.21
  Update dependency karma-spec-reporter to v0.0.33
  Update dependency karma-webpack to v4.0.2
  Update dependency karma-sourcemap-loader to v0.3.8
  Update dependency eslint-plugin-vue to v5.2.3
  Update dependency chromedriver to v87.0.7
  Update dependency @chenfengyuan/vue-qrcode to v1.0.2
  Pin dependencies
  Pin dependencies
  Do not mute bot posts in notifications
  Lint
  Add renovate.json
  Add bot indication to user icon on statuses
  Mute bot posts
  fix placeholder attachments opening new tab
2022-03-13 16:34:05 +02:00
HJ 51b14cc615 Merge branch 'eientei' into 'develop'
Mute bot posts filtering option

See merge request pleroma/pleroma-fe!1440
2022-03-13 14:04:15 +00:00
HJ 80bd6433aa Merge branch 'renovate/shelljs-0.x' into 'develop'
Update dependency shelljs to v0.8.5

See merge request pleroma/pleroma-fe!1455
2022-03-13 10:20:28 +00:00
HJ 50b3a30d1a Merge branch 'renovate/v-click-outside-2.x' into 'develop'
Update dependency v-click-outside to v2.1.5

See merge request pleroma/pleroma-fe!1456
2022-03-13 09:32:59 +00:00
Henry Jameson 5930b667a1 reduce the copypaste by making it more functional-style 2022-03-13 11:30:38 +02:00
Pleroma Renovate Bot 9b5ae4d4a3 Update dependency v-click-outside to v2.1.5 2022-03-13 09:04:54 +00:00
Pleroma Renovate Bot 22c8ad4583 Update dependency shelljs to v0.8.5 2022-03-13 09:04:46 +00:00
Henry Jameson 726fdbea15 remove "experimental" label from streaming api 2022-03-13 10:51:13 +02:00
HJ 67c2b52682 Merge branch 'renovate/portal-vue-2.x' into 'develop'
Update dependency portal-vue to v2.1.7

See merge request pleroma/pleroma-fe!1452
2022-03-13 08:20:20 +00:00
HJ 238e557d2b Merge branch 'renovate/lodash-monorepo' into 'develop'
Update dependency lodash to v4.17.21

See merge request pleroma/pleroma-fe!1451
2022-03-13 08:19:32 +00:00
HJ c8d87e7ef9 Merge branch 'renovate/karma-spec-reporter-0.x' into 'develop'
Update dependency karma-spec-reporter to v0.0.33

See merge request pleroma/pleroma-fe!1449
2022-03-12 09:30:01 +00:00
Pleroma Renovate Bot a83b07a629 Update dependency portal-vue to v2.1.7 2022-03-12 09:07:30 +00:00
Pleroma Renovate Bot 3bd2f3c36d Update dependency lodash to v4.17.21 2022-03-12 09:07:19 +00:00
Pleroma Renovate Bot 465c5f194c Update dependency karma-spec-reporter to v0.0.33 2022-03-12 09:07:05 +00:00
HJ ec3df8e5f2 Merge branch 'renovate/chromedriver-87.x' into 'develop'
Update dependency chromedriver to v87.0.7

See merge request pleroma/pleroma-fe!1446
2022-03-11 10:59:22 +00:00
HJ c194568daf Merge branch 'renovate/eslint-plugin-vue-5.x' into 'develop'
Update dependency eslint-plugin-vue to v5.2.3

See merge request pleroma/pleroma-fe!1447
2022-03-11 10:59:08 +00:00
HJ 63039aea37 Merge branch 'renovate/chenfengyuan-vue-qrcode-1.x' into 'develop'
Update dependency @chenfengyuan/vue-qrcode to v1.0.2

See merge request pleroma/pleroma-fe!1445
2022-03-11 09:15:37 +00:00
HJ fb803b2ff2 Merge branch 'renovate/karma-webpack-4.x' into 'develop'
Update dependency karma-webpack to v4.0.2

See merge request pleroma/pleroma-fe!1450
2022-03-11 09:13:27 +00:00
HJ fabac8524d Merge branch 'renovate/karma-sourcemap-loader-0.x' into 'develop'
Update dependency karma-sourcemap-loader to v0.3.8

See merge request pleroma/pleroma-fe!1448
2022-03-11 09:12:42 +00:00
Pleroma Renovate Bot 35ad2a1957 Update dependency karma-webpack to v4.0.2 2022-03-11 09:06:09 +00:00
Pleroma Renovate Bot e4d40fbba4 Update dependency karma-sourcemap-loader to v0.3.8 2022-03-11 09:05:47 +00:00
Pleroma Renovate Bot d4076e5df5 Update dependency eslint-plugin-vue to v5.2.3 2022-03-11 09:05:34 +00:00
Pleroma Renovate Bot 2ced27e734 Update dependency chromedriver to v87.0.7 2022-03-11 09:05:21 +00:00
Pleroma Renovate Bot 04d4f5525c Update dependency @chenfengyuan/vue-qrcode to v1.0.2 2022-03-11 09:05:09 +00:00
HJ 949f11ea1e Merge branch 'renovate/pin-dependencies' into 'develop'
Pin dependencies

See merge request pleroma/pleroma-fe!1443
2022-03-10 09:14:32 +00:00
Pleroma Renovate Bot 00a5dfc36f Pin dependencies 2022-03-10 09:06:57 +00:00
HJ e29f33ed0c Merge branch 'renovate/font-awesome' into 'develop'
Pin dependencies

See merge request pleroma/pleroma-fe!1444
2022-03-09 19:35:02 +00:00
Pleroma Renovate Bot 6946d09f55 Pin dependencies 2022-03-09 18:43:25 +00:00
Alexander Tumin 450145dd6b Do not mute bot posts in notifications 2022-03-09 07:56:43 +03:00
Tusooa Zhu 551b8f3690
Fix "max depth in thread" setting 2022-03-07 20:02:53 -05:00
Tusooa Zhu 48178bdc53
Make maxDepthInThread instance-default 2022-03-07 19:30:24 -05:00
Tusooa Zhu a511250b63
Make $status-margin fallback only 2022-03-07 19:28:38 -05:00
Tusooa Zhu 415a823af0
Clean up dead code 2022-03-07 19:19:32 -05:00
Tusooa Zhu 0e323ef248
Add English translations for fading ancestor option 2022-03-07 19:19:32 -05:00
Tusooa Zhu d157f67381
Make fading ancestors optional 2022-03-07 19:19:32 -05:00
Tusooa Zhu fa20ea76b1
Update English translation for tree view settings 2022-03-07 19:19:32 -05:00
Tusooa Zhu e7f5033c7d
Split conversation display style into two different settings
linear => linear (now default)
simple_tree => tree / conversationTreeAdvanced=false
tree => tree / conversationTreeAdvanced=true
2022-03-07 19:19:32 -05:00
Tusooa Zhu 9432fcec7d
Make 'Show full conversation' button have left border in embbeded mode 2022-03-07 19:19:32 -05:00
Tusooa Zhu 5768806d1b
Fix showingLongSubject not correctly propagated 2022-03-07 19:19:32 -05:00
Tusooa Zhu f8c5cbcd0d
Fix timeline jump when scrolling
Ref: tree-threading
2022-03-07 19:19:31 -05:00
Tusooa Zhu 20880cdf0b
Make replying and mediaPlaying controlled
$refs is not a reliable way to deal with child components under
tree threading as it is not reactive, but the children may change at
any time. The only good way seems to be making these states aggregated on
the conversation component.

Ref: tree-threading
2022-03-07 19:19:31 -05:00
Tusooa Zhu cc5cff2038
Clean up debug code for tree threading 2022-03-07 19:19:31 -05:00
Tusooa Zhu 2a510205c3
Fix virtual scrolling for tree threading
Ref: tree-threading
2022-03-07 19:19:31 -05:00
Tusooa Zhu 0db5a5a581
Fix controlled status display toggles 2022-03-07 19:19:31 -05:00
Tusooa Zhu ba858a894c
Add English translations for other replies count 2022-03-07 19:19:31 -05:00
Tusooa Zhu 654996fdbe
Add other replies count for reply list link 2022-03-07 19:19:31 -05:00
Tusooa Zhu cebb4224ac
Do not display replies inside status as link if there are no other replies 2022-03-07 19:19:31 -05:00
Tusooa Zhu 9b27ac9aaf
Add English translation for position of other replies button pref 2022-03-07 19:19:31 -05:00
Tusooa Zhu 863255d52f
Make position of other replies button a pref 2022-03-07 19:19:31 -05:00
Tusooa Zhu c4bd004cbc
Add English translation for show all conversation button improvement 2022-03-07 19:19:31 -05:00
Tusooa Zhu 244174a32b
Improve "show full conversation" interaction
Now we only show that button when there are other statuses out of sight
(other toplevel statuses exist outside of the current thread tree).
2022-03-07 19:19:31 -05:00
Tusooa Zhu 22bdcda9c0
Make other replies button stretch along the row 2022-03-07 19:19:31 -05:00
Tusooa Zhu ba8598858b
Optimise thread ancestor borders 2022-03-07 19:19:31 -05:00
Tusooa Zhu 17863f54fe
Optimise thread ancestor display style 2022-03-07 19:19:31 -05:00
Tusooa Zhu 26670e9003
Reset thread open state when collapsed 2022-03-07 19:19:30 -05:00
Tusooa Zhu 10cd03c718
Clean up 2022-03-07 19:19:30 -05:00
Tusooa Zhu f1db5e8f4b
Highlight ancestor of the current status when diving back to top 2022-03-07 19:19:30 -05:00
Tusooa Zhu d78c8e8ea4
Add English translation for Misskey-style tree view 2022-03-07 19:19:30 -05:00
Tusooa Zhu e560fbc935
Implement Misskey-style tree view
Now the tree will be always rooted at the highlighted status, and
all its ancestors shown linearly on the top.

Enhancement: If an ancestor has more
than one reply (i.e. it has a child that is not on current status's
ancestor chain), we are given a link to root the thread at that status.
2022-03-07 19:19:30 -05:00
Tusooa Zhu 4adffb4835
Remove horizontal border and thicken vertical border in a thread tree 2022-03-07 19:19:30 -05:00
Tusooa Zhu 0e4a7c3d05
Make dive/undive button clickable along the whole row 2022-03-07 19:19:30 -05:00
Tusooa Zhu 8780246ce5
Optimize thread border radius 2022-03-07 19:19:30 -05:00
Tusooa Zhu 61bb69c88f
Optimize thread display 2022-03-07 19:19:30 -05:00
Tusooa Zhu bdf631c2c4
Fix the bug where toggleShowingTall does not work 2022-03-07 19:19:30 -05:00
Tusooa Zhu 3addc36c96
Fix status undefined in parentOf 2022-03-07 19:19:30 -05:00
Tusooa Zhu f851bc92c9
Add English translations for max depth in thread 2022-03-07 19:19:30 -05:00
Tusooa Zhu 2e54cf12c7
Add settings for max depth in thread 2022-03-07 19:19:30 -05:00
Tusooa Zhu ff5f69b8fd
Use mergedConfig properly 2022-03-07 19:19:30 -05:00
Tusooa Zhu d7da9f80a7
Fallback to simpleTree style 2022-03-07 19:19:30 -05:00
Tusooa Zhu 6b990ba368
Undive when collapsed 2022-03-07 19:19:29 -05:00
Tusooa Zhu cd3e6d0073
Clean up 2022-03-07 19:19:29 -05:00
Tusooa Zhu 0aaef50ee5
Lint 2022-03-07 19:19:29 -05:00
Tusooa Zhu 05b2351e08
Add English translation for simple tree 2022-03-07 19:19:29 -05:00
Tusooa Zhu d9a9f97751
Add simple tree style navigation 2022-03-07 19:19:29 -05:00
Tusooa Zhu 8c0deb905e
Add English translation for diving 2022-03-07 19:19:29 -05:00
Tusooa Zhu d15d24c11c
Add dive functionality 2022-03-07 19:19:29 -05:00
Tusooa Zhu 31c4300456
Add English translations for diving 2022-03-07 19:19:29 -05:00
Tusooa Zhu 84a3cd92a3
Support diving into one status in a conversation 2022-03-07 19:19:29 -05:00
Tusooa Zhu ace1f5067c
Make status display controlled 2022-03-07 19:19:29 -05:00
Tusooa Zhu cd0f6a4f78
Add English translations for message threading 2022-03-07 19:19:29 -05:00
Tusooa Zhu 414ee55957
Make show full thread message account for numbers 2022-03-07 19:19:29 -05:00
Tusooa Zhu 0f2fd8a352
Implement thread folding/expanding 2022-03-07 19:19:29 -05:00
Tusooa Zhu 0582f19e7c
Add tree-style thread display 2022-03-07 19:19:29 -05:00
HJ 7e1e8ea429 Merge branch 'from/develop/tusooa/fix-lint-2' into 'develop'
Lint

See merge request pleroma/pleroma-fe!1442
2022-03-06 19:35:05 +00:00
Tusooa Zhu 7a8c975f61
Lint 2022-03-06 14:22:59 -05:00
HJ 1e41c2b99e Merge branch 'renovate/configure' into 'develop'
Configure Renovate

See merge request pleroma/pleroma-fe!1441
2022-03-06 18:25:05 +00:00
Pleroma Renovate Bot f0f1066bc8 Add renovate.json 2022-03-06 17:50:32 +00:00
Alexander Tumin 2b7f12613e Add bot indication to user icon on statuses 2022-03-01 01:00:38 +03:00
Alexander Tumin fe0ed7e8f0 Mute bot posts 2022-02-28 23:14:45 +03:00
HJ 514d7d3f88 Merge branch 'fix-hidden-attachments' into 'develop'
fix placeholder attachments opening new tab

Closes #1139

See merge request pleroma/pleroma-fe!1439
2022-02-28 17:46:58 +00:00
Henry Jameson 77b55a559b fix placeholder attachments opening new tab 2022-02-28 19:42:02 +02:00
Henry Jameson 77bb0b5530 lint 2022-02-28 18:23:32 +02:00
Henry Jameson 39909c8a85 pre-emptively wipe serverside settings on logout 2022-02-28 18:17:13 +02:00
Henry Jameson f4b36a9ebf fix errors in choicesetting 2022-02-28 18:15:21 +02:00
Henry Jameson 67319d0e5b fix typos in profile page 2022-02-28 18:15:07 +02:00
Henry Jameson cf58df17f6 hidden away more settings when logged out 2022-02-28 18:04:13 +02:00
Henry Jameson 8bb97fbfeb fix settings behaving erratically and not updating properly 2022-02-28 18:01:41 +02:00
Henry Jameson 3a5ad18aca fix stripping rich content not working 2022-02-28 18:00:38 +02:00
Henry Jameson e3d602fdcc revert changes related to streaming/firehose setting, reword it so it's
not confused with websocket streaming
2022-02-28 17:45:07 +02:00
Henry Jameson c07c0b2260 fix firefox rendering (??????????) 2022-02-28 17:43:08 +02:00
Henry Jameson f626da838a revert to using local setting for default nsfw since backend is broken 2022-02-24 15:00:08 +02:00
Henry Jameson 9623b0e140 better phrasing 2022-02-24 14:41:55 +02:00
Henry Jameson b1b9260a1d new defaults 2022-02-22 23:32:12 +02:00
Henry Jameson 9c1814d122 expert settings toggle + server-side settings 2022-02-22 23:31:40 +02:00
HJ 0300db6c63 Merge branch 'from/develop/tusooa/media-modal-counter-i18n' into 'develop'
Make media modal counter go through i18n

See merge request pleroma/pleroma-fe!1436
2022-02-21 16:15:16 +00:00
Tusooa Zhu c7690aecd0
Add English translation for media modal counter 2022-02-21 10:34:20 -05:00
Tusooa Zhu 1b32bb9c51
Make media modal counter go through i18n 2022-02-21 10:33:47 -05:00
HJ 9bc7d99e16 Merge branch 'hj-develop-patch-74637' into 'develop'
Update changelog

See merge request pleroma/pleroma-fe!1435
2022-02-21 14:23:11 +00:00
HJ 965bc5573f Update CHANGELOG.md 2022-02-21 14:17:28 +00:00
HJ 2559d03d7e Update CHANGELOG.md 2022-02-21 14:16:45 +00:00
HJ 58d0f9678b Merge branch 'fix-mentions-new-bugs' into 'develop'
Fix newfound bugs with rich mentions + user suggestions

See merge request pleroma/pleroma-fe!1430
2022-02-20 15:11:52 +00:00
HJ ddee8bb686 Merge branch 'proper-attachments' into 'develop'
Attachment improvements

See merge request pleroma/pleroma-fe!1399
2022-02-20 15:11:33 +00:00
HJ 56616787ec Merge branch 'fix-pinned-statuses' into 'develop'
Fix pinned statuses appearing at the bottom of user timeline

Closes #1112

See merge request pleroma/pleroma-fe!1433
2022-02-20 15:11:08 +00:00
HJ d3659b5597 Merge branch 'fix-1133' into 'develop'
fix #1133

Closes #1133

See merge request pleroma/pleroma-fe!1434
2022-02-20 14:12:20 +00:00
Henry Jameson 373c30be69 fix #1133 2022-02-20 16:06:26 +02:00
Henry Jameson 7b60adb480 only for user TL 2022-02-20 00:57:31 +02:00
Henry Jameson 5864dc52f7 removed file because that logic has been removed 2022-02-20 00:43:38 +02:00
Henry Jameson a31ff20f50 lol, lmao, that was some shit, this is much easier and works all the time 2022-02-20 00:36:21 +02:00
Henry Jameson 2a97bdb39d fix pinned statuses appearing at the bottom of user timeline (and
possibly fetching new ones there)
2022-02-20 00:04:47 +02:00
Henry Jameson 86e3aefdab new unit tests 2022-02-19 23:04:51 +02:00
Henry Jameson a8d1987686 fix unit tests 2022-02-19 22:40:19 +02:00
Henry Jameson 0d073d607c enable link handling in user bios to fix links not having _blank 2022-02-19 22:34:08 +02:00
Henry Jameson 769a9a14fe add emoji to chat titles 2022-02-19 22:30:13 +02:00
Henry Jameson a61f6e1590 use rich content in interaction lists 2022-02-19 22:12:37 +02:00
Henry Jameson ee86f56469 more spacing fixes 2022-02-11 15:10:52 +02:00
Henry Jameson 17d6f1b53b more spacing fixes 2022-02-11 15:06:12 +02:00
Henry Jameson befd4d5fc7 improve unknown attachment handling 2022-02-10 15:42:28 +02:00
Henry Jameson 4c7edfc9a9 more spacing/wrapping fixes 2022-02-09 23:34:26 +02:00
Henry Jameson d361a4d7dc fix overflows 2022-02-04 14:20:56 +02:00
Henry Jameson 571e73a346 better approach to unescaping 2022-02-03 23:13:28 +02:00
Henry Jameson 39ecb33883 fix amps in links 2022-02-03 22:58:12 +02:00
Henry Jameson 0f01931309 make chat messages behave same as posts for animated gifs 2022-02-03 22:52:41 +02:00
Henry Jameson a9830ff491 support width/height img attributes 2022-02-03 22:50:32 +02:00
Henry Jameson 9a6363431d lint 2022-02-03 22:41:38 +02:00
Henry Jameson ea6114f63c better phrasing? 2022-02-03 22:36:13 +02:00
Henry Jameson bfb3a4364b options to disable (You)s and highlighting of yourself 2022-02-03 22:34:57 +02:00
Henry Jameson 6d3229b1a1 fix poast mentions tripping 2022-02-03 22:23:28 +02:00
Henry Jameson 06042569f1 fix alignment issues 2022-02-03 22:10:45 +02:00
HJ 8ade11783a Merge branch 'from/develop/tusooa/1118-enhanced-mention-link' into 'develop'
Enhanced mention link

Closes #1118

See merge request pleroma/pleroma-fe!1424
2022-02-03 19:37:13 +00:00
HJ a5e20a4eb2 Merge branch 'from/develop/tusooa/fix-follow-list' into 'develop'
Fix Follow button missing on follow list

See merge request pleroma/pleroma-fe!1428
2022-02-03 10:22:22 +00:00
HJ dd75e43c57 Merge branch 'from/develop/tusooa/fix-lint-warn' into 'develop'
Fix lint warning in filtering_tab.vue

See merge request pleroma/pleroma-fe!1429
2022-02-03 10:22:04 +00:00
Tusooa Zhu 0e6af68a0f
Fix lint warning in filtering_tab.vue 2022-02-02 21:35:17 -05:00
Tusooa Zhu f886135bb7
Fix Follow button missing on follow list 2022-02-02 21:30:52 -05:00
Tusooa Zhu c3f1765b21
Hide mention link avatar by default 2022-01-29 16:57:59 -05:00
Tusooa Zhu 7cc0d0763c
Add English translation for mention link prefs 2022-01-29 16:57:59 -05:00
Tusooa Zhu c8983d5606
Make mention link prefs ui more intuitive 2022-01-29 16:57:59 -05:00
Tusooa Zhu 0c60b31eee
Add option to fade domains in mention link 2022-01-29 16:57:59 -05:00
Tusooa Zhu aaf0b985ad
Make avatar unselectable 2022-01-29 16:57:59 -05:00
Tusooa Zhu 9fde13c968
Add option to display user avatar in mention link 2022-01-29 16:57:59 -05:00
Tusooa Zhu 8896afd8d8
Make (You) unselectable 2022-01-29 16:57:59 -05:00
Tusooa Zhu 95007059d1
Style properly usernames without tooltips 2022-01-29 16:57:59 -05:00
Tusooa Zhu 1d4b1b296e
Add pref for whether to display full user names and tooltips 2022-01-29 16:57:59 -05:00
Tusooa Zhu 76547fe66d
Add a pref for whether to display mention as icon or text 2022-01-29 16:57:59 -05:00
FloatingGhost 41991bcac2 fix masto link handling 2022-01-29 13:09:55 +00:00
FloatingGhost 1bc05e87e4 apply patches 2022-01-28 19:07:28 +00:00
FloatingGhost f065fe98b2 Revert "fix hrefs"
This reverts commit aecc59cdc8.
2022-01-28 19:02:42 +00:00
FloatingGhost aecc59cdc8 fix hrefs 2022-01-28 18:45:21 +00:00
Henry Jameson d1f02221cb changelog 2022-01-24 21:44:41 +02:00
Henry Jameson efd558f394 Merge remote-tracking branch 'origin/develop' into proper-attachments
* origin/develop:
  Update CHANGELOG.md
2022-01-24 21:38:08 +02:00
HJ 28ee5721bb Merge branch 'hj-develop-patch-16931' into 'develop'
Update CHANGELOG.md

See merge request pleroma/pleroma-fe!1427
2022-01-24 19:31:42 +00:00
Henry Jameson 94c37e8adf Merge remote-tracking branch 'origin/develop' into proper-attachments
* origin/develop:
  undo accidental change when merging
  Apply 1 suggestion(s) to 1 file(s)
  Rearranged settings, moved more stuff to filtering where apllicable. Changed how filering works.
2022-01-24 21:29:19 +02:00
HJ e5f731c97d Update CHANGELOG.md 2022-01-24 19:29:01 +00:00
HJ 3cf7f9e3c8 Merge branch 'settings-and-filtering' into 'develop'
Settings rearrange and filtering improvements

See merge request pleroma/pleroma-fe!1394
2022-01-24 18:18:27 +00:00
Henry Jameson 56de3d2f52 fix too-many-attachments in notifications column 2022-01-24 19:53:17 +02:00
Henry Jameson c551e3e697 Merge remote-tracking branch 'origin/develop' into proper-attachments
* origin/develop: (81 commits)
  Improve the user card for deactivated users
  Update CHANGELOG.md
  Update CHANGELOG.md
  Allow canceling a follow request
  Simple policy reasons for instance specific policies
  entity_normalizer: Escape name when parsing user
  Translated using Weblate (Spanish)
  Translated using Weblate (Catalan)
  Translated using Weblate (Korean)
  Translated using Weblate (Japanese (ja_PEDANTIC))
  Translated using Weblate (Indonesian)
  Translated using Weblate (Esperanto)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Italian)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Indonesian)
  Translated using Weblate (Italian)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Indonesian)
  Translated using Weblate (Chinese (Simplified))
  ...
2022-01-24 19:28:38 +02:00
Henry Jameson f7e2ac1c48 undo accidental change when merging 2022-01-24 19:16:03 +02:00
Henry Jameson 2f8aae371b Merge remote-tracking branch 'origin/settings-and-filtering' into settings-and-filtering
* origin/settings-and-filtering:
  Apply 1 suggestion(s) to 1 file(s)
2022-01-24 19:13:29 +02:00
Henry Jameson 9ea0f10abb Merge remote-tracking branch 'origin/develop' into settings-and-filtering
* origin/develop: (169 commits)
  Improve the user card for deactivated users
  Update CHANGELOG.md
  Update CHANGELOG.md
  Allow canceling a follow request
  Simple policy reasons for instance specific policies
  entity_normalizer: Escape name when parsing user
  Translated using Weblate (Spanish)
  Translated using Weblate (Catalan)
  Translated using Weblate (Korean)
  Translated using Weblate (Japanese (ja_PEDANTIC))
  Translated using Weblate (Indonesian)
  Translated using Weblate (Esperanto)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Italian)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Indonesian)
  Translated using Weblate (Italian)
  Translated using Weblate (Vietnamese)
  Translated using Weblate (Indonesian)
  Translated using Weblate (Chinese (Simplified))
  ...
2022-01-24 19:12:17 +02:00
sadposter ecefbac4ec fix theme tab 2022-01-19 23:02:06 +00:00
HJ 182fcca5da Merge branch 'weblate-pleroma-pleroma-fe' into 'develop'
Translations update from Weblate

See merge request pleroma/pleroma-fe!1413
2022-01-19 13:10:16 +00:00
HJ 6509542dbd Merge branch 'fixes_for_deactivated_profile' into 'develop'
Improve the user card for deactivated users

See merge request pleroma/pleroma-fe!1417
2022-01-19 13:09:49 +00:00
Ilja 2ac78219ee Improve the user card for deactivated users 2022-01-19 13:09:48 +00:00
Shpuld Shpludson 756f7bf7c2 Merge branch 'shpuld-develop-patch-58245' into 'develop'
Update CHANGELOG.md

See merge request pleroma/pleroma-fe!1423
2022-01-09 18:29:46 +00:00
Shpuld Shpludson 4cd27acf7f Update CHANGELOG.md 2022-01-09 18:26:35 +00:00
Shpuld Shpludson 030c374def Merge branch 'shpuld-develop-patch-87791' into 'develop'
Update CHANGELOG.md

See merge request pleroma/pleroma-fe!1422
2022-01-09 18:21:14 +00:00
Shpuld Shpludson 056f5f547a Update CHANGELOG.md 2022-01-09 18:16:44 +00:00
HJ af2a408b78 Apply 1 suggestion(s) to 1 file(s) 2022-01-09 17:59:50 +00:00
sadposter dfb376cbd4 Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma-fe into develop 2021-12-30 21:09:22 +00:00
sadposter 1e39dac5ea i18n 2021-12-30 21:09:16 +00:00
HJ d22e04eaf6 Merge branch 'allow_to_cancel_follow_request' into 'develop'
Allow canceling a follow request

See merge request pleroma/pleroma-fe!1416
2021-12-28 11:43:24 +00:00
Ilja 4587f37dd7 Allow canceling a follow request
When a follow request is sent, but not (yet) accepted, the behaviour is now to cancel the request instead of re sending.

The reason is double
* You couldn't cancel a follow request if you change your mind and the request wasn't answered yet
* Instances don't always correctly process a new follow request when the following is already happening. If something went wrong (e;g. the target server thinks you're following, but your instance thinks you're not yet), it's better to first sent an unfollow. This is the behaviour that Mastodon and most probably most other clients have. Therefore this flow is more tested and expected by other instances.
2021-12-12 18:09:21 +01:00
sadposter e55f1c58df reduce polling rate 2021-12-05 15:02:10 +00:00
sadposter f150d0a105 Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma-fe into develop 2021-12-05 14:50:43 +00:00
sadposter fd9f78a7a1 use streaming API by default 2021-12-05 14:50:30 +00:00
HJ a20f1794d0 Merge branch 'simplePolicy_reasons_for_instance_specific_policies' into 'develop'
Simple policy reasons for instance specific policies

See merge request pleroma/pleroma-fe!1263
2021-12-03 18:14:32 +00:00
Ilja b4cfda4a20 Simple policy reasons for instance specific policies 2021-12-03 18:14:32 +00:00
sadposter 238ebcf1e4 remove svg 2021-11-20 14:38:01 +00:00
sadposter b141b04a53 Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma-fe into develop 2021-11-19 13:48:39 +00:00
HJ ea0887a15e Merge branch 'fix/escape-display-name' into 'develop'
entity_normalizer: Escape name when parsing user

See merge request pleroma/pleroma-fe!1415
2021-11-16 17:45:14 +00:00
rinpatch d36b45ad43 entity_normalizer: Escape name when parsing user
In January 2020 Pleroma backend stopped escaping HTML in display names
and passed that responsibility on frontends, compliant with Mastodon's
version of Mastodon API [1]. Pleroma-FE was subsequently modified to
escape the display name [2], however only in the "name_html" field. This
was fine however, since that's what the code rendering display names used.

However, 2 months ago an MR [3] refactoring the way the frontend does emoji
and mention rendering was merged. One of the things it did was moving away
from doing emoji rendering in the entity normalizer and use the unescaped
'user.name' in the rendering code, resulting in HTML injection being
possible again.

This patch escapes 'user.name' as well, as far as I can tell there is no
actual use for an unescaped display name in frontend code, especially
when it comes from MastoAPI, where it is not supposed to be HTML.

[1]: https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1052
[2]: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/2167
[3]: https://git.pleroma.social/pleroma/pleroma-fe/-/merge_requests/1392
2021-11-16 20:35:23 +03:00
tarteka d2730d5bad Translated using Weblate (Spanish)
Currently translated at 100.0% (722 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/es/
2021-10-21 19:22:22 +00:00
retiolus 1c75c74c91 Translated using Weblate (Catalan)
Currently translated at 99.7% (720 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-09-29 00:45:54 +00:00
Ryo Ueno ef684dff61 Translated using Weblate (Korean)
Currently translated at 61.9% (447 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ko/
2021-09-19 09:45:49 +00:00
Ryo Ueno 241b4957e1 Translated using Weblate (Japanese (ja_PEDANTIC))
Currently translated at 99.4% (718 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ja_PEDANTIC/
2021-09-19 09:45:49 +00:00
@liimee 45eda03d1c Translated using Weblate (Indonesian)
Currently translated at 68.1% (492 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-09-16 00:45:47 +00:00
Tirifto 1d0e4bada8 Translated using Weblate (Esperanto)
Currently translated at 100.0% (722 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2021-09-14 15:45:47 +00:00
Hồ Nhất Duy 3c8ced53b9 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (722 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/vi/
2021-09-09 22:00:26 +00:00
Ben Is 80dd6b2500 Translated using Weblate (Italian)
Currently translated at 100.0% (722 of 722 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-09-09 22:00:26 +00:00
Hồ Nhất Duy ad64b91d66 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/vi/
2021-09-09 22:00:26 +00:00
@liimee 4988268f5f Translated using Weblate (Indonesian)
Currently translated at 67.5% (484 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-09-09 22:00:26 +00:00
Ben Is 50adf0ddf2 Translated using Weblate (Italian)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-09-09 22:00:26 +00:00
HJ ef5bbc4e5f Merge branch 'themeApply' into 'develop'
Minor QOL improvement: Theme tab Apply and Reset buttons shouldn't require scrolling

See merge request pleroma/pleroma-fe!1397
2021-09-09 22:00:20 +00:00
HJ 370f1e55ad Merge branch 'develop' into 'themeApply'
# Conflicts:
#   CHANGELOG.md
2021-09-09 21:51:39 +00:00
HJ a8a82ad12f Merge branch 'showMobileNewPost' into 'develop'
New user option: Always show floating New Post button

See merge request pleroma/pleroma-fe!1395
2021-09-09 12:19:53 +00:00
HJ 1c53528433 Merge branch 'fix-favico-badge-chrome' into 'develop'
fix favico badge not working on chrome

See merge request pleroma/pleroma-fe!1391
2021-09-07 16:17:31 +00:00
HJ 8af1f08539 Merge branch 'better-still-emoji' into 'develop'
Status HTML parsing - better emoji and mentions rendering

Closes #935

See merge request pleroma/pleroma-fe!1392
2021-09-07 16:15:41 +00:00
Shpuld Shpludson 25a8b48bf2 Merge branch 'from/develop/tusooa/fix-mobile-shoutbox-display' into 'develop'
Fix mobile shoutbox display

See merge request pleroma/pleroma-fe!1404
2021-09-07 14:46:39 +00:00
HJ 59bab829a6 Merge branch 'weblate-pleroma-pleroma-fe' into 'develop'
Translations update from Weblate

See merge request pleroma/pleroma-fe!1412
2021-09-05 12:31:23 +00:00
Hồ Nhất Duy 13468f2a89 Translated using Weblate (Vietnamese)
Currently translated at 50.0% (358 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/vi/
2021-09-05 04:46:01 +00:00
@liimee 5bb471a68e Translated using Weblate (Indonesian)
Currently translated at 67.3% (482 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-09-05 04:45:45 +00:00
Kana ff5ed29ec1 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hans/
2021-09-05 04:45:43 +00:00
tarteka fa75a3a615 Translated using Weblate (Basque)
Currently translated at 80.7% (578 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eu/
2021-09-05 04:45:43 +00:00
HJ 057e3dac85 Merge branch 'weblate-pleroma-pleroma-fe' into 'develop'
Translations update from Weblate

See merge request pleroma/pleroma-fe!1388
2021-09-02 16:58:11 +00:00
Hồ Nhất Duy 6e57170626 Added translation using Weblate (Vietnamese) 2021-09-02 14:47:32 +00:00
sadposter e5db1a7e55 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-08-30 22:07:05 +01:00
@liimee 98da3ad124 Translated using Weblate (Indonesian)
Currently translated at 60.6% (434 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-08-30 15:24:16 +00:00
@liimee 144cee6d34 Translated using Weblate (Indonesian)
Currently translated at 58.6% (420 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-08-30 15:24:16 +00:00
tarteka 0543c8d536 Translated using Weblate (Basque)
Currently translated at 80.4% (576 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eu/
2021-08-30 15:24:16 +00:00
marcin mikołajczak 9319666f04 Translated using Weblate (Polish)
Currently translated at 98.8% (708 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/pl/
2021-08-30 15:24:16 +00:00
@liimee ca9652b30b Translated using Weblate (Indonesian)
Currently translated at 56.9% (408 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-08-30 15:24:16 +00:00
tarteka 21af736fe1 Translated using Weblate (Basque)
Currently translated at 79.8% (572 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eu/
2021-08-30 15:24:16 +00:00
tarteka 78ba8be969 Translated using Weblate (Spanish)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/es/
2021-08-30 15:24:16 +00:00
@liimee 29f229daad Translated using Weblate (Indonesian)
Currently translated at 50.1% (359 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/id/
2021-08-30 15:24:16 +00:00
marcin mikołajczak 5049ee575f Translated using Weblate (Polish)
Currently translated at 98.7% (707 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/pl/
2021-08-30 15:24:16 +00:00
tarteka 32ed71501a Translated using Weblate (Spanish)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/es/
2021-08-30 15:24:16 +00:00
@liimee a7a736c7b8 Added translation using Weblate (Indonesian) 2021-08-30 15:24:16 +00:00
tarteka 5cbb71e588 Translated using Weblate (Spanish)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/es/
2021-08-30 15:24:16 +00:00
M. Strange fa2e5deae2 Translated using Weblate (Catalan)
Currently translated at 97.4% (698 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:16 +00:00
titizen a3bfa63d05 Translated using Weblate (Catalan)
Currently translated at 95.3% (683 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:16 +00:00
M. Strange 1ef2bb93fe Translated using Weblate (Catalan)
Currently translated at 92.0% (659 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:16 +00:00
titizen c38ab7234d Translated using Weblate (Catalan)
Currently translated at 92.0% (659 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:16 +00:00
ZEN 791293c709 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/uk/
2021-08-30 15:24:16 +00:00
M. Strange 8574db1cf1 Translated using Weblate (Catalan)
Currently translated at 56.1% (402 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:15 +00:00
Snow 90d553f4be Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hant/
2021-08-30 15:24:15 +00:00
Haelwenn (lanodan) Monnier d3139a92b3 Translated using Weblate (French)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/fr/
2021-08-30 15:24:15 +00:00
Ben Is bc08f998cf Translated using Weblate (Italian)
Currently translated at 100.0% (716 of 716 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
Tirifto f72671a1aa Translated using Weblate (Esperanto)
Currently translated at 100.0% (715 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2021-08-30 15:24:15 +00:00
Ben Is 738e7923e4 Translated using Weblate (Italian)
Currently translated at 100.0% (715 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
retiolus b3f15fe3e1 Translated using Weblate (Catalan)
Currently translated at 44.4% (318 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/ca/
2021-08-30 15:24:15 +00:00
ZEN 761f91f7ef Translated using Weblate (Ukrainian)
Currently translated at 100.0% (715 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/uk/
2021-08-30 15:24:15 +00:00
Issabella Deinschnitzel c509ed357a Translated using Weblate (German)
Currently translated at 100.0% (715 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/de/
2021-08-30 15:24:15 +00:00
Ben Is 18871684c7 Translated using Weblate (Italian)
Currently translated at 100.0% (715 of 715 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
Kana 33e2bcce31 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (714 of 714 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/zh_Hans/
2021-08-30 15:24:15 +00:00
Ben Is 4d529c13ba Translated using Weblate (Italian)
Currently translated at 100.0% (714 of 714 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
Ben Is 0e53b2916e Translated using Weblate (Italian)
Currently translated at 100.0% (714 of 714 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
Tirifto 04a49e4c42 Translated using Weblate (Esperanto)
Currently translated at 99.7% (709 of 711 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/eo/
2021-08-30 15:24:15 +00:00
ZEN f57f61ca53 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (711 of 711 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/uk/
2021-08-30 15:24:15 +00:00
Ben Is 4302db5975 Translated using Weblate (Italian)
Currently translated at 100.0% (711 of 711 strings)

Translation: Pleroma/Pleroma-FE
Translate-URL: https://translate.pleroma.social/projects/pleroma/pleroma-fe/it/
2021-08-30 15:24:15 +00:00
Shpuld Shpludson cdcefc2b73 Merge branch 'fix-ext-profile' into 'develop'
fix ext profile bug

See merge request pleroma/pleroma-fe!1409
2021-08-30 15:24:06 +00:00
Henry Jameson 4d73eaa6ce fix spacing before hashtags 2021-08-23 21:36:18 +03:00
Henry Jameson 39494439d3 very minimalist hashtaglink implementation, also you can middle-click
mentions now.
2021-08-23 20:57:21 +03:00
Henry Jameson c3576211cb fix tests 2021-08-18 21:17:51 +03:00
Henry Jameson cbb34e2b0e fix expanded mentions spacing 2021-08-18 20:58:26 +03:00
Henry Jameson e98a2af39e hopefully final fix for spacings 2021-08-18 20:54:04 +03:00
Henry Jameson dbdc5e050f fix ext profile bug 2021-08-16 01:41:52 +03:00
Henry Jameson 49fe334186 play gifs when hovering over notification 2021-08-16 01:34:35 +03:00
Henry Jameson 14ec7d6a41 add attachment counter 2021-08-16 01:11:43 +03:00
Henry Jameson 7cc19ef2ea better media modal loading 2021-08-16 01:11:42 +03:00
Henry Jameson 0507eb6550 ability to move attachments around when making a new post 2021-08-15 21:04:49 +03:00
Henry Jameson 830a03a0d1 inline description display 2021-08-15 21:04:28 +03:00
Henry Jameson 34d265467a add media description into media modal 2021-08-15 19:45:48 +03:00
Henry Jameson f5823a96e9 add key attribute to make image refresh in media modal to give feedback
when images are still loaded
2021-08-15 19:43:52 +03:00
Henry Jameson 777f6c0162 Merge branch 'better-still-emoji' into proper-attachments
* better-still-emoji:
  fix "+X more" sticking
2021-08-15 18:43:52 +03:00
Henry Jameson 0087d33c75 fix "+X more" sticking 2021-08-15 18:41:13 +03:00
Henry Jameson 299c00cf74 fix video attachments in notifications not having pointer cursor 2021-08-15 18:35:26 +03:00
Henry Jameson 07c12ae162 replace poll with an icon in notifications 2021-08-15 18:26:37 +03:00
Henry Jameson c8a7b6f433 fix long posts double-fading in notifications 2021-08-15 18:21:25 +03:00
Henry Jameson 5431d8fe55 Merge branch 'better-still-emoji' into proper-attachments
* better-still-emoji:
  fix links sticking to mentionsline
2021-08-15 18:11:57 +03:00
Henry Jameson 8cc1ad67df fix links sticking to mentionsline 2021-08-15 18:11:38 +03:00
Henry Jameson 6aa6f6f300 fix console errors 2021-08-15 17:53:35 +03:00
Henry Jameson 17d2eed06a Merge branch 'better-still-emoji' into proper-attachments
* better-still-emoji:
  fix tests
  prevent infinite update loops
  remove obsolete tests
  removed useless code, review change, fixed bug with tall statuses
  fixed mentions line again
  remove old emoji added, everything emoji-bearing uses RichContent now
  richcontent support in polls, user cards and user profiles
  support richcontent in polls
  fix tests, add performance test (skipped, doesn't assert anything), tweak max mentions count
  made the code responsible for showing unwritten mentions actually work
  remove new options for style and separate line, now groups all chained mentions on a mentionsline regardless of placement. fixes spacing
  fix tests
2021-08-15 16:27:41 +03:00
Henry Jameson f16658adfc fix tests 2021-08-15 02:59:14 +03:00
Henry Jameson 68b4323181 prevent infinite update loops 2021-08-15 02:55:45 +03:00
Henry Jameson 7d67e8f1cc remove obsolete tests 2021-08-15 02:44:36 +03:00
Henry Jameson 530ac4442b removed useless code, review change, fixed bug with tall statuses 2021-08-15 02:41:53 +03:00
Henry Jameson 4465de5241 fixed mentions line again 2021-08-14 22:03:09 +03:00
Henry Jameson 97e86381c8 remove old emoji added, everything emoji-bearing uses RichContent now 2021-08-13 13:12:33 +03:00
Henry Jameson 4c974f5ca2 richcontent support in polls, user cards and user profiles 2021-08-13 13:06:42 +03:00
Henry Jameson 6c6df29ed3 support richcontent in polls 2021-08-13 12:19:57 +03:00
Henry Jameson add5921b8b fix tests, add performance test (skipped, doesn't assert anything),
tweak max mentions count
2021-08-12 19:37:04 +03:00
Henry Jameson 2182af4058 made the code responsible for showing unwritten mentions actually work 2021-08-12 03:09:28 +03:00
Henry Jameson 2cfff1b8b9 remove new options for style and separate line, now groups all chained
mentions on a mentionsline regardless of placement. fixes spacing
2021-08-12 02:56:40 +03:00
sadposter feb7090cde Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-08-05 12:59:18 +01:00
Tusooa Zhu ef277ae4e2
Fix mobile shoutbox 2021-08-03 20:11:06 -04:00
eris f35e3d0f3f Fix merge conflict in CHANGELOG
# Conflicts:
#   CHANGELOG.md
2021-07-22 20:47:36 +00:00
eris 179af131ee Fix changelog merge conflict
# Conflicts:
#   CHANGELOG.md
2021-07-22 20:46:41 +00:00
FloatingGhost 9cea1bc08c fix preset 2021-07-01 16:47:16 +01:00
sadposter d49434a799 add stuff 2021-07-01 16:06:59 +01:00
sadposter 214d85189c Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-06-25 10:07:29 +01:00
Henry Jameson a0eaac2216 fix tests 2021-06-22 21:09:29 +03:00
Henry Jameson b67db47c88 lint 2021-06-22 20:47:35 +03:00
Henry Jameson dd3fe61cf3 Merge branch 'better-still-emoji' into proper-attachments
* better-still-emoji:
  fix non-notifying mentions and original mention display
  fix not escaping some stuff
  fix rich images
2021-06-22 20:45:44 +03:00
Henry Jameson a2f21f4e13 fix description colliding with extra-long text 2021-06-22 20:42:52 +03:00
Henry Jameson 628b99d117 don't stretch columns when uploading media 2021-06-22 20:37:08 +03:00
Henry Jameson 5118eee19a fix videos not stretching to container 2021-06-22 20:35:34 +03:00
Henry Jameson 4ba8d95a10 fix videos and related not having working drag controls 2021-06-22 20:33:57 +03:00
Henry Jameson 4016182b89 fix z-indexes 2021-06-22 20:32:55 +03:00
Henry Jameson a258182522 fix non-notifying mentions and original mention display 2021-06-22 20:16:26 +03:00
eris 6125dc885a Update for latest develop merges to CHANGELOG 2021-06-20 21:06:59 +00:00
Henry Jameson c6831a3810 fix not escaping some stuff 2021-06-18 21:42:46 +03:00
Henry Jameson 8fe4355a6b fix rich images 2021-06-18 21:29:47 +03:00
Henry Jameson 6b8b9c017f whoops 2021-06-18 17:39:29 +03:00
Henry Jameson 44b741e270 better attachments in uploading (grid layout) 2021-06-18 17:30:56 +03:00
Henry Jameson 8bab8658e8 better handling of unknown files, better upload display 2021-06-18 16:11:16 +03:00
Henry Jameson bfe31e20ea better compact attachments 2021-06-18 14:12:50 +03:00
Henry Jameson 5c2744b426 Merge branch 'better-still-emoji' into proper-attachments
* better-still-emoji:
  Use proper setting name
  Use cleaner instance config check for shoutbox setting
  Make locale language cleaner
  Don't shorten shoutbox to SB
  Fix lint error
  Update CHANGELOG.md
  New option: Hide shoutbox
2021-06-18 02:28:11 +03:00
Henry Jameson b68fb7738b Merge remote-tracking branch 'origin/develop' into better-still-emoji
* origin/develop:
  Use proper setting name
  Use cleaner instance config check for shoutbox setting
  Make locale language cleaner
  Don't shorten shoutbox to SB
  Fix lint error
  Update CHANGELOG.md
  New option: Hide shoutbox
2021-06-18 02:27:57 +03:00
Henry Jameson f35c090caa merged in compact notifs and improved upon it 2021-06-18 02:27:32 +03:00
Henry Jameson c1293c3afa Merge branch 'compact-notifs' into proper-attachments
* compact-notifs:
  compact notifs
2021-06-18 02:09:50 +03:00
Henry Jameson f15599e6e5 gallery in post status form! 2021-06-18 02:04:01 +03:00
Henry Jameson 90345f158f gallery now supports flash, fixes for flash component. refactored media modal 2021-06-18 02:03:38 +03:00
Henry Jameson e654fead23 refactored attachments and gallery. All attachments now are in gallery. 2021-06-17 16:29:46 +03:00
Eris 9c4957268d Use proper setting name 2021-06-17 13:21:25 +03:00
Eris 6689fed513 Use cleaner instance config check for shoutbox setting 2021-06-17 13:21:25 +03:00
Eris 4ecbb58086 Make locale language cleaner 2021-06-17 13:21:25 +03:00
Eris 0a3ce9cc8b Don't shorten shoutbox to SB 2021-06-17 13:21:25 +03:00
Eris dcfd178314 Fix lint error 2021-06-17 13:21:25 +03:00
Eris 1b26c713ef Update CHANGELOG.md 2021-06-17 13:21:25 +03:00
Eris 9e9ab5cec9 New option: Hide shoutbox 2021-06-17 13:21:25 +03:00
Henry Jameson a96a62929d Merge remote-tracking branch 'origin/develop' into settings-and-filtering
* origin/develop:
  Use proper setting name
  Use cleaner instance config check for shoutbox setting
  Make locale language cleaner
  Don't shorten shoutbox to SB
  Fix lint error
  Update CHANGELOG.md
  New option: Hide shoutbox
2021-06-16 13:52:13 +03:00
Henry Jameson 1717a3aaf2 fix chats again 2021-06-16 12:44:04 +03:00
Henry Jameson 25bf28f051 added tests just in case 2021-06-16 02:11:24 +03:00
Henry Jameson ad3a2fd4e5 fixed "invisible" spans inside links 2021-06-16 01:20:20 +03:00
eris 139a0d1562 Merge branch 'develop' into 'themeApply'
# Conflicts:
#   CHANGELOG.md
2021-06-15 21:50:39 +00:00
eris cab0095989 Merge branch 'develop' into 'showMobileNewPost'
# Conflicts:
#   CHANGELOG.md
#   src/App.js
2021-06-15 21:49:33 +00:00
Henry Jameson 4aac0125e5 fixed bug with hashtags 2021-06-15 14:43:44 +03:00
Eris e67f295497 Update CHANGELOG.md 2021-06-14 23:32:18 +00:00
Eris 312a237ca4 Revert duplicate buttons and move existing buttons to bottom-right corner independent of scroll 2021-06-14 23:31:16 +00:00
Eris 4639e30cb8 Fix config naming for consistency 2021-06-14 20:41:34 +00:00
Eris b88e6b8ab0 Update CHANGELOG.md 2021-06-14 20:11:57 +00:00
Eris 8fa0331771 Add apply and reset themes to top of theme tab 2021-06-14 20:09:28 +00:00
Eris 67c9d8bd55 revert gitignore file change 2021-06-14 18:49:37 +00:00
Eris adfe56a3a3 New option: Always show floating New Post button 2021-06-14 17:54:40 +00:00
Henry Jameson 7309f8ce1a lint 2021-06-14 10:31:07 +03:00
Henry Jameson c21b1cf898 do the impossible, fix the unfixable 2021-06-14 10:30:08 +03:00
Henry Jameson a3c703bd37 compact notifs 2021-06-14 02:52:41 +03:00
Henry Jameson 636dbdaba8 more fixes 2021-06-13 22:22:59 +03:00
Henry Jameson 1fdfc42159 fix mentions in chats 2021-06-13 21:43:45 +03:00
Henry Jameson 609dc5da0c fix chats messages 2021-06-13 21:42:25 +03:00
Henry Jameson bebafa1a2c refactored line converter, untied its logic from greentexting, better
handling of broken cases
2021-06-13 15:24:29 +03:00
HJ e825021ef1 Apply 1 suggestion(s) to 1 file(s) 2021-06-12 18:55:18 +00:00
Henry Jameson 9c70f3e4df fixed a bug + made a testcase out of it 2021-06-12 21:49:56 +03:00
Henry Jameson 2c60a9b638 fix next relply-row bleeding through popover 2021-06-12 20:51:36 +03:00
Henry Jameson 18fb7516cc lint 2021-06-12 20:44:14 +03:00
Henry Jameson 418f029789 review + fixes 2021-06-12 20:43:29 +03:00
Henry Jameson 90a188f2c3 cleanup 2021-06-12 19:54:34 +03:00
Henry Jameson cd44556750 restructure and tests
squash! restructure and tests
2021-06-12 19:54:30 +03:00
Henry Jameson ca6c7d5b10 fix tags gluing 2021-06-12 17:20:21 +03:00
Henry Jameson 24f3681ac1 fix color of reply row, fix overflow in status-popover 2021-06-12 17:11:49 +03:00
Henry Jameson 647e4476f9 fix long post fader 2021-06-12 16:25:37 +03:00
Henry Jameson c1bd36dc6f change how "first" line is determined. Allow one mention in the
beginning for hellthread style
2021-06-12 16:15:22 +03:00
Henry Jameson ffc501eb23 cleanup 2021-06-11 13:38:08 +03:00
Henry Jameson 9421501c1e lint & cleanup 2021-06-11 11:52:50 +03:00
Henry Jameson 5834790d0b fix #935 2021-06-11 11:50:05 +03:00
Henry Jameson f819227bed fixed console errors, improved user-selecting, added cyantexting 2021-06-11 11:49:32 +03:00
Henry Jameson 255f47fe56 fix infinite loop 2021-06-11 11:05:28 +03:00
Henry Jameson f883d2f75c better handling of hellthreads with mentions at bottom 2021-06-11 03:11:58 +03:00
Henry Jameson b84aeff6bf stylistic changes 2021-06-10 18:52:23 +03:00
Henry Jameson cc00af7a31 Hellthread(tm) Certified 2021-06-10 18:52:01 +03:00
Henry Jameson 0f73e96194 don't hide mentions for OPs 2021-06-10 15:11:57 +03:00
Henry Jameson 0263834faa mentions on same line as replies 2021-06-10 14:01:26 +03:00
Henry Jameson 6bff7cc6ef use icon instead of symbol for @ in mentions links 2021-06-10 13:29:59 +03:00
Henry Jameson 0260693f51 stylistic improvements for single-line mentions 2021-06-10 13:22:36 +03:00
Henry Jameson 394fd462dc proper cachin of headTailLinks, show mentions in notificaitons always 2021-06-10 13:01:00 +03:00
Henry Jameson c6c478f4cf moved mentions onto reply line, replies moved below post body 2021-06-10 12:29:58 +03:00
Henry Jameson aec867b300 Moved greentext to RichContent, improved how first mentions are
restored, now shows mentions not uh, mention in post body
2021-06-10 12:29:58 +03:00
Henry Jameson 566964992a fix long posts having weird gradient 2021-06-08 19:37:18 +03:00
Henry Jameson 5c655b6675 lint 2021-06-08 17:19:38 +03:00
Henry Jameson 8c8237418c fix repeats having wrong mentions 2021-06-08 17:14:22 +03:00
Henry Jameson 963f1679e0 fix console errors 2021-06-08 17:14:22 +03:00
Henry Jameson a3b8e7ad99 missing localization 2021-06-08 16:37:13 +03:00
Henry Jameson b87a9d6675 Rearranged settings, moved more stuff to filtering where apllicable.
Changed how filering works.
2021-06-08 16:14:01 +03:00
Henry Jameson 7ae85c8318 change defaults 2021-06-08 14:51:42 +03:00
Henry Jameson 0ae3985a52 bump limit to a saner one 2021-06-08 14:36:41 +03:00
Henry Jameson 2f383c2c01 moved mentions into a separate component - MentionLine, added collapsing
of mentions when there's too many of 'em
2021-06-08 14:34:47 +03:00
Henry Jameson 73127f0e25 fix empty spaces again 2021-06-08 13:42:16 +03:00
Henry Jameson 9ea370033a configurable mentions placement 2021-06-08 12:58:28 +03:00
Henry Jameson 3abd357694 moving mentions into separate row 2021-06-08 11:38:44 +03:00
Henry Jameson 0583a6b863 moved transparent button styles into button itself 2021-06-08 10:14:49 +03:00
Henry Jameson 6bc9886db4 tweaking the spacings 2021-06-08 01:25:03 +03:00
Henry Jameson ccdf892483 remove weird vertical align 2021-06-08 01:21:45 +03:00
Henry Jameson 5740a79dbd faint @ 2021-06-08 00:06:26 +03:00
Henry Jameson e6d5ddcbb6 better modifier, no background for unhighlighted mentions 2021-06-08 00:03:59 +03:00
Henry Jameson c3e122ff6f smaller mentions 2021-06-07 23:48:01 +03:00
Henry Jameson 7d6fc044fb new mentions look 2021-06-07 23:42:04 +03:00
Henry Jameson 6199788f28 fix tall emojis being cropped 2021-06-07 20:44:32 +03:00
Henry Jameson 8045d1866e localization 2021-06-07 20:25:31 +03:00
Henry Jameson 6090327236 moved some post styles into status body since they inferfere with usernames 2021-06-07 20:02:09 +03:00
Henry Jameson 5e83672274 fixed some strange error 2021-06-07 20:01:57 +03:00
Henry Jameson aa38223e87 lint 2021-06-07 19:51:04 +03:00
Henry Jameson 8e9f5d7580 renamed StatusText to StatusBody for clarity, fixed chats 2021-06-07 19:50:38 +03:00
Henry Jameson 50aa379038 new component - StatusText, to separate post's text from its attachments 2021-06-07 18:41:55 +03:00
Henry Jameson 04fa1f0b2d some docs, added richcontent to usernames in status, updated stillImage
to allow scale of "gif" label
2021-06-07 18:41:47 +03:00
Henry Jameson aec05686d0 lint, fix warnings 2021-06-07 18:41:47 +03:00
Henry Jameson b0ae32e309 made getAttrs correctly handle both ' and " 2021-06-07 18:41:47 +03:00
Henry Jameson 22c8f71945 mention link 2021-06-07 18:41:47 +03:00
Henry Jameson 1923ed84d4 more tests 2021-06-07 18:41:47 +03:00
Henry Jameson a2459c2187 move styles to richcontent 2021-06-07 18:41:47 +03:00
Henry Jameson be79643bcf fix emoji processor not leaving string as-is if no emoji are found 2021-06-07 18:41:47 +03:00
Henry Jameson 35dedf8416 lint 2021-06-07 18:41:47 +03:00
Henry Jameson 5970ddf9ac fix escaped apostrophes 2021-06-07 18:41:47 +03:00
Henry Jameson 20ce646852 [WIP] MUCH better approach to replacing emojis with still versions 2021-06-07 18:41:47 +03:00
Henry Jameson 2a2483f4c9 handle multiple favicons (different sizes) 2021-06-02 12:47:54 +03:00
Henry Jameson 008e711e11 fix favico badge not working on chrome 2021-06-02 12:15:31 +03:00
sadposter 28ac9d83c1 Merge branch 'develop' of gitssh.ihatebeinga.live:IHBAGang/pleroma-fe into develop 2021-05-21 11:42:10 +01:00
FloatingGhost 6d47156297 Merge branch 'develop' of https://git.ihatebeinga.live/IHBAGang/pleroma-fe into develop 2021-05-21 11:37:33 +01:00
FloatingGhost cda1819d81 Add domain block components 2021-05-21 11:35:50 +01:00
sadposter dd6fb78913 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-05-12 16:16:18 +01:00
sadposter 350d0b0888 things 2021-05-12 16:16:13 +01:00
Henry Jameson 8a9115b58e temp fix for now-unused resettable async component 2021-04-25 14:51:15 +03:00
Henry Jameson b6e8c12dbc emoji picker fix 2021-04-25 14:51:00 +03:00
Henry Jameson e73cb423b6 fix login form 2021-04-25 14:44:07 +03:00
Henry Jameson e47d5ba53b fix importer/exporter i18n 2021-04-25 14:12:34 +03:00
Henry Jameson 8d46fd78c7 migrate to v-slot 2021-04-25 14:05:25 +03:00
Henry Jameson 95e74319e1 clean warnings from status 2021-04-25 14:05:25 +03:00
Henry Jameson 709b75198d fix portals/teleports 2021-04-25 14:05:25 +03:00
Henry Jameson caed89f0ae destroyed -> unmounted 2021-04-25 13:44:50 +03:00
Henry Jameson 72956e2343 fix HOCs 2021-04-25 13:40:08 +03:00
Henry Jameson 4b18e0f36e fix status error 2021-04-25 13:33:02 +03:00
Henry Jameson b479d80366 fix i18n in services 2021-04-25 13:30:18 +03:00
Henry Jameson 9e8513b312 i18n fixes 2021-04-25 13:25:42 +03:00
Henry Jameson 52835cf8bf work around modules cyclic dependencies 2021-04-25 13:25:04 +03:00
Henry Jameson 905b9771ec stop using vue.set 2021-04-25 13:24:08 +03:00
Henry Jameson fca885e665 resolve TODO VUE3 2021-04-25 13:23:16 +03:00
Henry Jameson 6e687c0663 fix one async component preventing further load 2021-04-25 13:15:02 +03:00
Henry Jameson 180da297f6 Merge branch 'vue3compat-tabswitcher' into vue3-again
* vue3compat-tabswitcher:
  small refactoring to uncouple tab-switcher from settings modal
  fix theme tab, remove console.logs
  Changed some of TabSwitcher's internals for easier Vue3 migration
2021-04-25 12:51:45 +03:00
Henry Jameson b774472fff Merge branch 'vue3compat-emoji-input' into vue3-again
* vue3compat-emoji-input:
  backport vue3 changes related to emoji-input
2021-04-25 12:51:21 +03:00
Henry Jameson 76a2e6befb remove Vue.component from hooks 2021-04-25 12:50:17 +03:00
Henry Jameson 1f5f612163 remove Vue.component, just export an object. Seems to be working 2021-04-25 12:47:52 +03:00
Henry Jameson 509ec99574 some minor fixes to get it to boot 2021-04-24 18:04:35 +03:00
Henry Jameson ced9c0fa7e some bare minimum to get vue3 boot (no UI yet) 2021-04-24 17:56:00 +03:00
Henry Jameson 33777fab47 small refactoring to uncouple tab-switcher from settings modal 2021-04-18 15:39:06 +03:00
Henry Jameson b0789fd6fd fix theme tab, remove console.logs 2021-04-18 15:03:28 +03:00
Henry Jameson 433ea02a18 Changed some of TabSwitcher's internals for easier Vue3 migration 2021-04-18 14:58:02 +03:00
sadposter 50d5ef7416 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-03-30 11:48:05 +01:00
sadposter c7c4e2e03e Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-03-23 23:01:44 +00:00
sadposter d1bffd7659 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-03-03 13:51:57 +00:00
sadposter 7ed1fe70d1 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-02-20 15:29:27 +00:00
sadposter 87ae0eaa15 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2021-01-23 22:45:25 +00:00
sadposter edb5826072 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-12-29 13:25:38 +00:00
sadposter 7e1b1ec990 :Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-11-15 19:45:52 +00:00
sadposter 804e25084d thing 2020-11-15 19:45:14 +00:00
sadposter e21dd584a9 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-11-01 12:26:14 +00:00
sadposter 3f8845bdad Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-09-15 17:29:57 +01:00
sadposter 098991d767 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-09-09 09:45:48 +01:00
sadposter d44d8f1989 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-08-24 17:29:34 +01:00
sadposter 763d2c0ce4 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-08-13 20:15:30 +01:00
sadposter 66c44b4260 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-08-01 19:41:12 +01:00
sadposter 6f621dd34c Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-07-10 11:27:53 +01:00
sadposter 954d5c05df Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-07-09 22:32:18 +01:00
sadposter 77bd79100b Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-06-19 11:01:06 +01:00
sadposter f99240df69 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-06-06 18:30:38 +01:00
sadposter 78db835fe1 Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop 2020-05-20 17:16:21 +01:00
sadposter b4ca079bdb dd nsfw 2020-05-20 17:15:34 +01:00
sadposter 10153e692e ihba updates 2020-05-08 14:38:46 +01:00
333 changed files with 18457 additions and 6434 deletions

View file

@ -1,5 +1,5 @@
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-transform-vue-jsx"],
"plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"],
"comments": false
}

View file

@ -21,6 +21,8 @@ module.exports = {
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'vue/require-prop-types': 0
'vue/require-prop-types': 0,
'vue/no-unused-vars': 0,
'no-tabs': 0
}
}

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ test/e2e/reports
selenium-debug.log
.idea/
config/local.json
config/local.*.json

View file

@ -1,7 +1,7 @@
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
image: node:10
image: node:12
stages:
- lint

54
.woodpecker.yml Normal file
View file

@ -0,0 +1,54 @@
pipeline:
lint:
when:
event:
- push
- pull_request
image: node:16
commands:
- yarn
- yarn lint
- yarn stylelint
test:
when:
event:
- push
- pull_request
image: node:16
commands:
- apt update
- apt install firefox-esr -y --no-install-recommends
- yarn
- yarn unit
build:
when:
event:
- push
branch:
- develop
image: node:16
commands:
- yarn
- yarn build
release:
when:
event:
- push
branch:
- develop
image: node:16
secrets:
- SCW_ACCESS_KEY
- SCW_SECRET_KEY
- SCW_DEFAULT_ORGANIZATION_ID
commands:
- apt-get update && apt-get install -y rclone wget zip
- wget https://github.com/scaleway/scaleway-cli/releases/download/v2.5.1/scaleway-cli_2.5.1_linux_amd64
- mv scaleway-cli_2.5.1_linux_amd64 scaleway-cli
- chmod +x scaleway-cli
- ./scaleway-cli object config install type=rclone
- zip akkoma-fe.zip -r dist
- rclone copyto akkoma-fe.zip scaleway:akkoma-updates/frontend/akkoma-fe.zip

View file

@ -3,6 +3,57 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
### Fixed
- AdminFE button no longer scrolls page to top when clicked
- Pinned statuses no longer appear at bottom of user timeline (still appear as part of the timeline when fetched deep enough)
- Fixed many many bugs related to new mentions, including spacing and alignment issues
- Links in profile bios now properly open in new tabs
- Inline images now respect their intended width/height attributes
- Links with `&` in them work properly now
- Interaction list popovers now properly emojify names
- Completely hidden posts still had 1px border
- Attachments are ALWAYS in same order as user uploaded, no more "videos first"
- Attachment description is prefilled with backend-provided default when uploading
- Proper visual feedback that next image is loading when browsing
### Changed
- (You)s are optional (opt-in) now, bolding your nickname is also optional (opt-out)
- User highlight background now also covers the `@`
- Reverted back to textual `@`, svg version is opt-in.
- Settings window has been throughly rearranged to make make more sense and make navication settings easier.
- Uploaded attachments are uniform with displayed attachments
- Flash is watchable in media-modal (takes up nearly full screen though due to sizing issues)
- Notifications about likes/repeats/emoji reacts are now minimized so they always take up same amount of space irrelevant to size of post.
### Added
- Options to show domains in mentions
- Option to show user avatars in mention links (opt-in)
- Option to disable the tooltip for mentions
- Option to completely hide muted threads
- Ability to open videos in modal even if you disabled that feature, via an icon button
- New button on attachment that indicates that attachment has a description and shows a bar filled with description
- Attachments are truncated just like post contents
- Media modal now also displays description and counter position in gallery (i.e. 1/5)
- Ability to rearrange order of attachments when uploading
- Enabled users to zoom and pan images in media viewer with mouse and touch
- Added frontend ui for account migration
## [2.4.2] - 2022-01-09
### Added
- Added Apply and Reset buttons to the bottom of theme tab to minimize UI travel
- Implemented user option to always show floating New Post button (normally mobile-only)
- Display reasons for instance specific policies
- Added functionality to cancel follow request
### Fixed
- Fixed link to external profile not working on user profiles
- Fixed mobile shoutbox display
- Fixed favicon badge not working in Chrome
- Escape html more properly in subject/display name
## [2.4.0] - 2021-08-08
### Added
- Added a quick settings to timeline header for easier access
@ -15,6 +66,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- Fixed follow request count showing in the wrong location in mobile view
## [2.3.0] - 2021-03-01
### Fixed
- Button to remove uploaded media in post status form is now properly placed and sized.

View file

@ -4,6 +4,7 @@ var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')
var ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin')
var CopyPlugin = require('copy-webpack-plugin');
var { VueLoaderPlugin } = require('vue-loader')
var env = process.env.NODE_ENV
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
@ -29,16 +30,16 @@ module.exports = {
}
},
resolve: {
extensions: ['.js', '.vue'],
extensions: ['.js', '.jsx', '.vue'],
modules: [
path.join(__dirname, '../node_modules')
],
alias: {
'vue$': 'vue/dist/vue.runtime.common',
'static': path.resolve(__dirname, '../static'),
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components')
'components': path.resolve(__dirname, '../src/components'),
'vue-i18n': 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js'
}
},
module: {
@ -58,9 +59,28 @@ module.exports = {
}
}
},
{
enforce: 'post',
test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
type: 'javascript/auto',
loader: '@intlify/vue-i18n-loader',
include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
path.resolve(__dirname, '../src/i18n')
]
},
{
test: /\.vue$/,
use: 'vue-loader'
loader: 'vue-loader',
options: {
compilerOptions: {
isCustomElement(tag) {
if (tag === 'pinch-zoom') {
return true
}
return false
}
}
}
},
{
test: /\.jsx?$/,
@ -95,6 +115,7 @@ module.exports = {
entry: path.join(__dirname, '..', 'src/sw.js'),
filename: 'sw-pleroma.js'
}),
new VueLoaderPlugin(),
// This copies Ruffle's WASM to a directory so that JS side can access it
new CopyPlugin({
patterns: [

View file

@ -21,7 +21,9 @@ module.exports = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': config.dev.env,
'COMMIT_HASH': JSON.stringify('DEV'),
'DEV_OVERRIDES': JSON.stringify(config.dev.settings)
'DEV_OVERRIDES': JSON.stringify(config.dev.settings),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),

View file

@ -36,7 +36,9 @@ var webpackConfig = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': env,
'COMMIT_HASH': JSON.stringify(commitHash),
'DEV_OVERRIDES': JSON.stringify(undefined)
'DEV_OVERRIDES': JSON.stringify(undefined),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
}),
// extract css into its own file
new MiniCssExtractPlugin({

View file

@ -52,7 +52,10 @@ module.exports = {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true
ws: true,
headers: {
'Origin': target
}
},
'/oauth/revoke': {
target,

View file

@ -3,6 +3,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<title>Pleroma</title>
<link rel="stylesheet" href="/static/font/css/fontello.css">
<link rel="stylesheet" href="/static/font/css/animation.css">
<link rel="stylesheet" href="/static/font/tiresias.css">
<link rel="stylesheet" href="/static/font/css/lato.css">
<link rel="stylesheet" href="/static/mfm.css">
<!--server-generated-meta-->
<link rel="icon" type="image/png" href="/favicon.png">
</head>

View file

@ -16,107 +16,113 @@
"lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs"
},
"dependencies": {
"@babel/runtime": "^7.7.6",
"@chenfengyuan/vue-qrcode": "^1.0.0",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-regular-svg-icons": "^5.15.1",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/vue-fontawesome": "^2.0.0",
"body-scroll-lock": "^2.6.4",
"chromatism": "^3.0.0",
"cropperjs": "^1.4.3",
"diff": "^3.0.1",
"escape-html": "^1.0.3",
"localforage": "^1.5.0",
"parse-link-header": "^1.0.1",
"phoenix": "^1.3.0",
"portal-vue": "^2.1.4",
"punycode.js": "^2.1.0",
"ruffle-mirror": "^2021.4.10",
"v-click-outside": "^2.1.1",
"vue": "^2.6.11",
"vue-i18n": "^7.3.2",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.6.11",
"vuelidate": "^0.7.4",
"vuex": "^3.0.1"
"@babel/runtime": "7.17.8",
"@chenfengyuan/vue-qrcode": "2.0.0",
"@fortawesome/fontawesome-svg-core": "1.3.0",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "3.0.0-5",
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
"@vuelidate/core": "2.0.0-alpha.41",
"@vuelidate/validators": "2.0.0-alpha.27",
"body-scroll-lock": "2.7.1",
"chromatism": "3.0.0",
"click-outside-vue3": "4.0.1",
"cropperjs": "1.5.12",
"diff": "3.5.0",
"escape-html": "1.0.3",
"js-cookie": "^3.0.1",
"localforage": "1.10.0",
"mfm-js": "^0.22.1",
"parse-link-header": "1.0.1",
"phoenix": "1.6.2",
"punycode.js": "2.1.0",
"qrcode": "1",
"ruffle-mirror": "2021.12.31",
"vue": "^3.2.31",
"vue-i18n": "^9.2.0-beta.34",
"vue-router": "4.0.14",
"vue-template-compiler": "2.6.11",
"vuex": "4.0.2"
},
"devDependencies": {
"@babel/core": "^7.7.5",
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.6",
"@babel/register": "^7.7.4",
"@ungap/event-target": "^0.1.0",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
"@vue/test-utils": "^1.0.0-beta.26",
"autoprefixer": "^6.4.0",
"babel-eslint": "^7.0.0",
"babel-loader": "^8.0.6",
"babel-plugin-lodash": "^3.3.4",
"chai": "^3.5.0",
"chalk": "^1.1.3",
"chromedriver": "^87.0.1",
"connect-history-api-fallback": "^1.1.0",
"copy-webpack-plugin": "^6.4.1",
"cross-spawn": "^4.0.2",
"css-loader": "^0.28.0",
"custom-event-polyfill": "^1.0.7",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^2.0.5",
"eslint-loader": "^2.1.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-node": "^7.0.0",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.2",
"eventsource-polyfill": "^0.9.6",
"express": "^4.13.3",
"file-loader": "^3.0.1",
"function-bind": "^1.0.2",
"html-webpack-plugin": "^3.0.0",
"http-proxy-middleware": "^0.17.2",
"inject-loader": "^2.0.1",
"iso-639-1": "^2.0.3",
"isparta-loader": "^2.0.0",
"json-loader": "^0.5.4",
"karma": "^3.0.0",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.1.0",
"karma-mocha": "^1.2.0",
"karma-mocha-reporter": "^2.2.1",
"karma-sinon-chai": "^2.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.26",
"karma-webpack": "^4.0.0-rc.3",
"lodash": "^4.16.4",
"lolex": "^1.4.0",
"mini-css-extract-plugin": "^0.5.0",
"mocha": "^3.1.0",
"nightwatch": "^0.9.8",
"opn": "^4.0.2",
"ora": "^0.3.0",
"postcss-loader": "^3.0.0",
"raw-loader": "^0.5.1",
"sass": "^1.17.3",
"sass-loader": "git://github.com/webpack-contrib/sass-loader",
"@babel/core": "7.17.8",
"@babel/plugin-transform-runtime": "7.17.0",
"@babel/preset-env": "7.16.11",
"@babel/register": "7.17.7",
"@intlify/vue-i18n-loader": "^5.0.0",
"@ungap/event-target": "0.2.3",
"@vue/babel-helper-vue-jsx-merge-props": "1.2.1",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/compiler-sfc": "^3.1.0",
"@vue/test-utils": "2.0.0-rc.17",
"autoprefixer": "6.7.7",
"babel-eslint": "7.2.3",
"babel-loader": "8.2.4",
"babel-plugin-lodash": "3.3.4",
"chai": "3.5.0",
"chalk": "1.1.3",
"chromedriver": "87.0.7",
"connect-history-api-fallback": "1.6.0",
"copy-webpack-plugin": "6.4.1",
"cross-spawn": "4.0.2",
"css-loader": "0.28.11",
"custom-event-polyfill": "1.0.7",
"eslint": "5.16.0",
"eslint-config-standard": "12.0.0",
"eslint-friendly-formatter": "2.0.7",
"eslint-loader": "2.2.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-node": "7.0.1",
"eslint-plugin-promise": "4.3.1",
"eslint-plugin-standard": "4.1.0",
"eslint-plugin-vue": "5.2.3",
"eventsource-polyfill": "0.9.6",
"express": "4.17.3",
"file-loader": "3.0.1",
"function-bind": "1.1.1",
"html-webpack-plugin": "3.2.0",
"http-proxy-middleware": "0.21.0",
"inject-loader": "2.0.1",
"iso-639-1": "2.1.13",
"isparta-loader": "2.0.0",
"json-loader": "0.5.7",
"karma": "6.3.17",
"karma-coverage": "1.1.2",
"karma-firefox-launcher": "1.3.0",
"karma-mocha": "2.0.1",
"karma-mocha-reporter": "2.2.5",
"karma-sinon-chai": "2.0.2",
"karma-sourcemap-loader": "0.3.8",
"karma-spec-reporter": "0.0.33",
"karma-webpack": "4.0.2",
"lodash": "4.17.21",
"lolex": "1.6.0",
"mini-css-extract-plugin": "0.12.0",
"mocha": "3.5.3",
"nightwatch": "0.9.21",
"opn": "4.0.2",
"ora": "0.4.1",
"postcss-loader": "3.0.0",
"raw-loader": "0.5.1",
"sass": "1.20.1",
"sass-loader": "7.2.0",
"selenium-server": "2.53.1",
"semver": "^5.3.0",
"serviceworker-webpack-plugin": "^1.0.0",
"shelljs": "^0.8.4",
"sinon": "^2.1.0",
"sinon-chai": "^2.8.0",
"stylelint": "^13.6.1",
"stylelint-config-standard": "^20.0.0",
"stylelint-rscss": "^0.4.0",
"url-loader": "^1.1.2",
"vue-loader": "^14.0.0",
"vue-style-loader": "^4.0.0",
"webpack": "^4.44.0",
"webpack-dev-middleware": "^3.6.0",
"webpack-hot-middleware": "^2.12.2",
"webpack-merge": "^0.14.1"
"semver": "5.7.1",
"serviceworker-webpack-plugin": "1.0.1",
"shelljs": "0.8.5",
"sinon": "2.4.1",
"sinon-chai": "2.14.0",
"stylelint": "13.6.1",
"stylelint-config-standard": "20.0.0",
"stylelint-rscss": "0.4.0",
"url-loader": "1.1.2",
"vue-loader": "^16.0.0",
"vue-style-loader": "4.1.2",
"webpack": "4.46.0",
"webpack-dev-middleware": "3.7.3",
"webpack-hot-middleware": "2.24.3",
"webpack-merge": "0.20.0"
},
"engines": {
"node": ">= 4.0.0",

6
renovate.json Normal file
View file

@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}

View file

@ -1,6 +1,5 @@
import UserPanel from './components/user_panel/user_panel.vue'
import NavPanel from './components/nav_panel/nav_panel.vue'
import Notifications from './components/notifications/notifications.vue'
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
@ -16,13 +15,14 @@ import PostStatusModal from './components/post_status_modal/post_status_modal.vu
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
import { mapGetters } from 'vuex'
import { defineAsyncComponent } from 'vue'
export default {
name: 'app',
components: {
UserPanel,
NavPanel,
Notifications,
Notifications: defineAsyncComponent(() => import('./components/notifications/notifications.vue')),
InstanceSpecificPanel,
FeaturesPanel,
WhoToFollowPanel,
@ -46,10 +46,20 @@ export default {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
window.addEventListener('resize', this.updateMobileState)
},
destroyed () {
unmounted () {
window.removeEventListener('resize', this.updateMobileState)
},
computed: {
classes () {
return [
{
'-reverse': this.reverseLayout,
'-no-sticky-headers': this.noSticky,
'-has-new-post-button': this.newPostButtonShown
},
'-' + this.layoutType
]
},
currentUser () { return this.$store.state.users.currentUser },
userBackground () { return this.currentUser.background_image },
instanceBackground () {
@ -65,35 +75,45 @@ export default {
}
}
},
shout () { return this.$store.state.shout.channel.state === 'joined' },
shout () { return this.$store.state.shout.joined },
suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled },
showInstanceSpecificPanel () {
return this.$store.state.instance.showInstanceSpecificPanel &&
!this.$store.getters.mergedConfig.hideISP &&
this.$store.state.instance.instanceSpecificPanelContent
},
isChats () {
return this.$route.name === 'chat' || this.$route.name === 'chats'
},
newPostButtonShown () {
if (this.isChats) return false
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
},
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
shoutboxPosition () {
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
},
hideShoutbox () {
return this.$store.getters.mergedConfig.hideShoutbox
},
isMobileLayout () { return this.$store.state.interface.mobileLayout },
layoutType () { return this.$store.state.interface.layoutType },
privateMode () { return this.$store.state.instance.private },
sidebarAlign () {
return {
'order': this.$store.getters.mergedConfig.sidebarRight ? 99 : 0
reverseLayout () {
const { thirdColumnMode, sidebarRight: reverseSetting } = this.$store.getters.mergedConfig
if (this.layoutType !== 'wide') {
return reverseSetting
} else {
return thirdColumnMode === 'notifications' ? reverseSetting : !reverseSetting
}
},
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
showScrollbars () { return this.$store.getters.mergedConfig.showScrollbars },
...mapGetters(['mergedConfig'])
},
methods: {
updateMobileState () {
const mobileLayout = windowWidth() <= 800
const layoutHeight = windowHeight()
const changed = mobileLayout !== this.isMobileLayout
if (changed) {
this.$store.dispatch('setMobileLayout', mobileLayout)
}
this.$store.dispatch('setLayoutHeight', layoutHeight)
this.$store.dispatch('setLayoutWidth', windowWidth())
this.$store.dispatch('setLayoutHeight', windowHeight())
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,39 +1,40 @@
<template>
<div
id="app"
id="app-loaded"
:style="bgStyle"
>
<div
id="app_bg_wrapper"
class="app-bg-wrapper"
/>
<MobileNav v-if="isMobileLayout" />
<MobileNav v-if="layoutType === 'mobile'" />
<DesktopNav v-else />
<div class="app-bg-wrapper app-container-wrapper" />
<Notifications v-if="currentUser" />
<div
id="content"
class="container underlay"
class="app-layout container"
:class="classes"
>
<div class="underlay" />
<div
class="sidebar-flexer mobile-hidden"
:style="sidebarAlign"
id="sidebar"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
>
<div class="sidebar-bounds">
<div class="sidebar-scroller">
<div class="sidebar">
<user-panel />
<div v-if="!isMobileLayout">
<nav-panel />
<instance-specific-panel v-if="showInstanceSpecificPanel" />
<features-panel v-if="!currentUser && showFeaturesPanel" />
<who-to-follow-panel v-if="currentUser && suggestionsEnabled" />
<notifications v-if="currentUser" />
</div>
</div>
</div>
</div>
<user-panel />
<template v-if="layoutType !== 'mobile'">
<nav-panel />
<instance-specific-panel v-if="showInstanceSpecificPanel" />
<features-panel v-if="!currentUser && showFeaturesPanel" />
<who-to-follow-panel v-if="currentUser && suggestionsEnabled" />
<div id="notifs-sidebar" />
</template>
</div>
<div class="main">
<div
id="main-scroller"
class="column main"
:class="{ '-full-height': isChats }"
>
<div
v-if="!currentUser"
class="login-hint panel panel-default"
@ -47,18 +48,24 @@
</div>
<router-view />
</div>
<media-modal />
<div
id="notifs-column"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
/>
</div>
<media-modal />
<shout-panel
v-if="currentUser && shout && !hideShoutbox"
:floating="true"
class="floating-shout mobile-hidden"
:class="{ '-left': shoutboxPosition }"
/>
<MobilePostStatusButton />
<UserReportingModal />
<PostStatusModal />
<SettingsModal />
<portal-target name="modal" />
<div id="modal" />
<GlobalNoticeList />
</div>
</template>

View file

@ -30,3 +30,5 @@ $fallback--attachmentRadius: 10px;
$fallback--chatMessageRadius: 10px;
$fallback--buttonShadow: 0px 0px 2px 0px rgba(0, 0, 0, 1), 0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
$status-margin: 0.75em;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -1,8 +1,14 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import vClickOutside from 'click-outside-vue3'
import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
import App from '../App.vue'
import { windowWidth } from '../services/window_utils/window_utils'
import routes from './routes'
import VBodyScrollLock from 'src/directives/body_scroll_lock'
import { windowWidth, windowHeight } from '../services/window_utils/window_utils'
import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
@ -115,6 +121,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
copyInstanceOption('nsfwCensorImage')
copyInstanceOption('background')
copyInstanceOption('hidePostStats')
copyInstanceOption('hideBotIndication')
copyInstanceOption('hideUserStats')
copyInstanceOption('hideFilteredStatuses')
copyInstanceOption('logo')
@ -325,8 +332,8 @@ const checkOAuthToken = async ({ store }) => {
}
const afterStoreSetup = async ({ store, i18n }) => {
const width = windowWidth()
store.dispatch('setMobileLayout', width <= 800)
store.dispatch('setLayoutWidth', windowWidth())
store.dispatch('setLayoutHeight', windowHeight())
FaviconService.initFaviconService()
@ -366,25 +373,32 @@ const afterStoreSetup = async ({ store, i18n }) => {
getTOS({ store })
getStickers({ store })
const router = new VueRouter({
mode: 'history',
const router = createRouter({
history: createWebHistory(),
routes: routes(store),
scrollBehavior: (to, _from, savedPosition) => {
if (to.matched.some(m => m.meta.dontScroll)) {
return false
}
return savedPosition || { x: 0, y: 0 }
return savedPosition || { left: 0, top: 0 }
}
})
/* eslint-disable no-new */
return new Vue({
router,
store,
i18n,
el: '#app',
render: h => h(App)
})
const app = createApp(App)
app.use(router)
app.use(store)
app.use(i18n)
app.use(vClickOutside)
app.use(VBodyScrollLock)
app.component('FAIcon', FontAwesomeIcon)
app.component('FALayers', FontAwesomeLayers)
app.mount('#app')
return app
}
export default afterStoreSetup

View file

@ -20,6 +20,9 @@ import ShoutPanel from 'components/shout_panel/shout_panel.vue'
import WhoToFollow from 'components/who_to_follow/who_to_follow.vue'
import About from 'components/about/about.vue'
import RemoteUserResolver from 'components/remote_user_resolver/remote_user_resolver.vue'
import Lists from 'components/lists/lists.vue'
import ListTimeline from 'components/list_timeline/list_timeline.vue'
import ListEdit from 'components/list_edit/list_edit.vue'
export default (store) => {
const validateAuthenticatedRoute = (to, from, next) => {
@ -46,7 +49,7 @@ export default (store) => {
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
{ name: 'remote-user-profile-acct',
path: '/remote-users/(@?):username([^/@]+)@:hostname([^/@]+)',
path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)',
component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute
},
@ -62,14 +65,17 @@ export default (store) => {
{ name: 'password-reset', path: '/password-reset', component: PasswordReset, props: true },
{ name: 'registration-token', path: '/registration/:token', component: Registration },
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests, beforeEnter: validateAuthenticatedRoute },
{ name: 'notifications', path: '/:username/notifications', component: Notifications, beforeEnter: validateAuthenticatedRoute },
{ name: 'notifications', path: '/:username/notifications', component: Notifications, props: () => ({ disableTeleport: true }), beforeEnter: validateAuthenticatedRoute },
{ name: 'login', path: '/login', component: AuthForm },
{ name: 'shout-panel', path: '/shout-panel', component: ShoutPanel, props: () => ({ floating: false }) },
{ name: 'oauth-callback', path: '/oauth-callback', component: OAuthCallback, props: (route) => ({ code: route.query.code }) },
{ name: 'search', path: '/search', component: Search, props: (route) => ({ query: route.query.query }) },
{ name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute },
{ name: 'about', path: '/about', component: About },
{ name: 'user-profile', path: '/(users/)?:name', component: UserProfile }
{ name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile },
{ name: 'lists', path: '/lists', component: Lists },
{ name: 'list-timeline', path: '/lists/:id', component: ListTimeline },
{ name: 'list-edit', path: '/lists/:id/edit', component: ListEdit }
]
if (store.state.instance.pleromaChatMessagesAvailable) {

View file

@ -1,5 +1,5 @@
<template>
<div class="sidebar">
<div class="column-inner">
<instance-specific-panel v-if="showInstanceSpecificPanel" />
<staff-panel />
<terms-of-service-panel />

View file

@ -40,7 +40,7 @@ const AccountActions = {
openChat () {
this.$router.push({
name: 'chat',
params: { recipient_id: this.user.id }
params: { username: this.$store.state.users.currentUser.screen_name, recipient_id: this.user.id }
})
}
},

View file

@ -74,10 +74,6 @@
<style lang="scss">
@import '../../_variables.scss';
.AccountActions {
button.dropdown-item {
margin-left: 0;
}
.ellipsis-button {
width: 2.5em;
margin: -0.5em 0;

View file

@ -19,6 +19,7 @@
<script>
export default {
emits: ['resetAsyncComponent'],
methods: {
retry () {
this.$emit('resetAsyncComponent')

View file

@ -11,7 +11,12 @@ import {
faImage,
faVideo,
faPlayCircle,
faTimes
faTimes,
faStop,
faSearchPlus,
faTrashAlt,
faPencilAlt,
faAlignRight
} from '@fortawesome/free-solid-svg-icons'
library.add(
@ -20,27 +25,39 @@ library.add(
faImage,
faVideo,
faPlayCircle,
faTimes
faTimes,
faStop,
faSearchPlus,
faTrashAlt,
faPencilAlt,
faAlignRight
)
const Attachment = {
props: [
'attachment',
'description',
'hideDescription',
'nsfw',
'size',
'allowPlay',
'setMedia',
'naturalSizeLoad'
'remove',
'shiftUp',
'shiftDn',
'edit'
],
data () {
return {
localDescription: this.description || this.attachment.description,
nsfwImage: this.$store.state.instance.nsfwCensorImage || nsfwImage,
hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw,
preloadImage: this.$store.getters.mergedConfig.preloadImage,
loading: false,
img: fileTypeService.fileType(this.attachment.mimetype) === 'image' && document.createElement('img'),
modalOpen: false,
showHidden: false
showHidden: false,
flashLoaded: false,
showDescription: false
}
},
components: {
@ -49,8 +66,23 @@ const Attachment = {
VideoAttachment
},
computed: {
classNames () {
return [
{
'-loading': this.loading,
'-nsfw-placeholder': this.hidden,
'-editable': this.edit !== undefined
},
'-type-' + this.type,
this.size && '-size-' + this.size,
`-${this.useContainFit ? 'contain' : 'cover'}-fit`
]
},
usePlaceholder () {
return this.size === 'hide' || this.type === 'unknown'
return this.size === 'hide'
},
useContainFit () {
return this.$store.getters.mergedConfig.useContainFit
},
placeholderName () {
if (this.attachment.description === '' || !this.attachment.description) {
@ -74,24 +106,33 @@ const Attachment = {
return this.nsfw && this.hideNsfwLocal && !this.showHidden
},
isEmpty () {
return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
},
isSmall () {
return this.size === 'small'
},
fullwidth () {
if (this.size === 'hide') return false
return this.type === 'html' || this.type === 'audio' || this.type === 'unknown'
return (this.type === 'html' && !this.attachment.oembed)
},
useModal () {
const modalTypes = this.size === 'hide' ? ['image', 'video', 'audio']
: this.mergedConfig.playVideosInModal
? ['image', 'video']
: ['image']
let modalTypes = []
switch (this.size) {
case 'hide':
case 'small':
modalTypes = ['image', 'video', 'audio', 'flash']
break
default:
modalTypes = this.mergedConfig.playVideosInModal
? ['image', 'video', 'flash']
: ['image']
break
}
return modalTypes.includes(this.type)
},
videoTag () {
return this.useModal ? 'button' : 'span'
},
...mapGetters(['mergedConfig'])
},
watch: {
localDescription (newVal) {
this.onEdit(newVal)
}
},
methods: {
linkClicked ({ target }) {
if (target.tagName === 'A') {
@ -100,12 +141,37 @@ const Attachment = {
},
openModal (event) {
if (this.useModal) {
event.stopPropagation()
event.preventDefault()
this.setMedia()
this.$store.dispatch('setCurrent', this.attachment)
this.$emit('setMedia')
this.$store.dispatch('setCurrentMedia', this.attachment)
} else if (this.type === 'unknown') {
window.open(this.attachment.url)
}
},
openModalForce (event) {
this.$emit('setMedia')
this.$store.dispatch('setCurrentMedia', this.attachment)
},
onEdit (event) {
this.edit && this.edit(this.attachment, event)
},
onRemove () {
this.remove && this.remove(this.attachment)
},
onShiftUp () {
this.shiftUp && this.shiftUp(this.attachment)
},
onShiftDn () {
this.shiftDn && this.shiftDn(this.attachment)
},
stopFlash () {
this.$refs.flash.closePlayer()
},
setFlashLoaded (event) {
this.flashLoaded = event
},
toggleDescription () {
this.showDescription = !this.showDescription
},
toggleHidden (event) {
if (
(this.mergedConfig.useOneClickNsfw && !this.showHidden) &&
@ -132,7 +198,27 @@ const Attachment = {
onImageLoad (image) {
const width = image.naturalWidth
const height = image.naturalHeight
this.naturalSizeLoad && this.naturalSizeLoad({ width, height })
this.$emit('naturalSizeLoad', { id: this.attachment.id, width, height })
},
resize (e) {
const target = e.target || e
if (!(target instanceof window.Element)) { return }
// Reset to default height for empty form, nothing else to do here.
if (target.value === '') {
target.style.height = null
this.$emit('resize')
return
}
const paddingString = getComputedStyle(target)['padding']
// remove -px suffix
const padding = Number(paddingString.substring(0, paddingString.length - 2))
target.style.height = 'auto'
const newHeight = Math.floor(target.scrollHeight - padding * 2)
target.style.height = `${newHeight}px`
this.$emit('resize', newHeight)
}
}
}

View file

@ -0,0 +1,282 @@
@import '../../_variables.scss';
.Attachment {
display: inline-flex;
flex-direction: column;
position: relative;
align-self: flex-start;
line-height: 0;
height: 100%;
border-style: solid;
border-width: 1px;
border-radius: $fallback--attachmentRadius;
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
.attachment-wrapper {
flex: 1 1 auto;
height: 200px;
position: relative;
overflow: hidden;
}
.description-container {
flex: 0 1 0;
display: flex;
padding-top: 0.5em;
z-index: 1;
p {
flex: 1;
text-align: center;
line-height: 1.5;
padding: 0.5em;
margin: 0;
white-space: pre-line;
word-break: break-word;
text-overflow: ellipsis;
overflow: hidden;
}
&.-static {
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding-top: 0;
background: var(--popover);
box-shadow: var(--popupShadow);
}
}
.description-field {
flex: 1;
min-width: 0;
box-sizing: content-box;
overflow: hidden;
transition: min-height 200ms 100ms;
padding-bottom: var(--_padding);
height: calc(var(--post-line-height) * 1em);
min-height: calc(var(--post-line-height) * 1em);
resize: none;
&.scrollable-form {
overflow-y: auto;
}
}
& .placeholder-container,
& .image-container,
& .audio-container,
& .video-container,
& .flash-container,
& .oembed-container {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.image-container {
.image {
width: 100%;
height: 100%;
}
}
& .flash-container,
& .video-container {
& .flash,
& video {
width: 100%;
height: 100%;
object-fit: contain;
align-self: center;
}
}
.audio-container {
display: flex;
align-items: flex-end;
audio {
width: 100%;
height: 100%;
}
}
.placeholder-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 0.5em;
}
.play-icon {
position: absolute;
font-size: 64px;
top: calc(50% - 32px);
left: calc(50% - 32px);
color: rgba(255, 255, 255, 0.75);
text-shadow: 0 0 2px rgba(0, 0, 0, 0.4);
&::before {
margin: 0;
}
}
.attachment-buttons {
display: flex;
position: absolute;
right: 0;
top: 0;
margin-top: 0.5em;
margin-right: 0.5em;
z-index: 1;
.attachment-button {
padding: 0;
border-radius: $fallback--tooltipRadius;
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
text-align: center;
width: 2em;
height: 2em;
margin-left: 0.5em;
font-size: 1.25em;
// TODO: theming? hard to theme with unknown background image color
background: rgba(230, 230, 230, 0.7);
.svg-inline--fa {
color: rgba(0, 0, 0, 0.6);
}
&:hover .svg-inline--fa {
color: rgba(0, 0, 0, 0.9);
}
}
}
.oembed-container {
line-height: 1.2em;
flex: 1 0 100%;
width: 100%;
margin-right: 15px;
display: flex;
img {
width: 100%;
}
.image {
flex: 1;
img {
border: 0px;
border-radius: 5px;
height: 100%;
object-fit: cover;
}
}
.text {
flex: 2;
margin: 8px;
word-break: break-all;
h1 {
font-size: 1rem;
margin: 0px;
}
}
}
&.-size-small {
.play-icon {
zoom: 0.5;
opacity: 0.7;
}
.attachment-buttons {
zoom: 0.7;
opacity: 0.5;
}
}
&.-editable {
padding: 0.5em;
& .description-container,
& .attachment-buttons {
margin: 0;
}
}
&.-placeholder {
display: inline-block;
color: $fallback--link;
color: var(--postLink, $fallback--link);
overflow: hidden;
white-space: nowrap;
height: auto;
line-height: 1.5;
&:not(.-editable) {
border: none;
}
&.-editable {
display: flex;
flex-direction: row;
align-items: baseline;
& .description-container,
& .attachment-buttons {
margin: 0;
padding: 0;
position: relative;
}
.description-container {
flex: 1;
padding-left: 0.5em;
}
.attachment-buttons {
order: 99;
align-self: center;
}
}
a {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
svg {
color: inherit;
}
}
&.-loading {
cursor: progress;
}
&.-contain-fit {
img,
canvas {
object-fit: contain;
}
}
&.-cover-fit {
img,
canvas {
object-fit: cover;
}
}
}

View file

@ -1,7 +1,8 @@
<template>
<div
<button
v-if="usePlaceholder"
:class="{ 'fullwidth': fullwidth }"
class="Attachment -placeholder button-unstyled"
:class="classNames"
@click="openModal"
>
<a
@ -11,318 +12,258 @@
:href="attachment.url"
:alt="attachment.description"
:title="attachment.description"
@click.prevent
>
<FAIcon :icon="placeholderIconClass" />
<b>{{ nsfw ? "NSFW / " : "" }}</b>{{ placeholderName }}
<b>{{ nsfw ? "NSFW / " : "" }}</b>{{ edit ? '' : placeholderName }}
</a>
</div>
<div
v-if="edit || remove"
class="attachment-buttons"
>
<button
v-if="remove"
class="button-unstyled attachment-button"
@click.prevent="onRemove"
>
<FAIcon icon="trash-alt" />
</button>
</div>
<div
v-if="size !== 'hide' && !hideDescription && (edit || localDescription || showDescription)"
class="description-container"
:class="{ '-static': !edit }"
>
<input
v-if="edit"
v-model="localDescription"
type="text"
class="description-field"
:placeholder="$t('post_status.media_description')"
@keydown.enter.prevent=""
>
<p v-else>
{{ localDescription }}
</p>
</div>
</button>
<div
v-else
v-show="!isEmpty"
class="attachment"
:class="{[type]: true, loading, 'fullwidth': fullwidth, 'nsfw-placeholder': hidden}"
class="Attachment"
:class="classNames"
>
<a
v-if="hidden"
class="image-attachment"
:href="attachment.url"
:alt="attachment.description"
:title="attachment.description"
@click.prevent.stop="toggleHidden"
>
<img
:key="nsfwImage"
class="nsfw"
:src="nsfwImage"
:class="{'small': isSmall}"
>
<FAIcon
v-if="type === 'video'"
class="play-icon"
icon="play-circle"
/>
</a>
<button
v-if="nsfw && hideNsfwLocal && !hidden"
class="button-unstyled hider"
@click.prevent="toggleHidden"
>
<FAIcon icon="times" />
</button>
<a
v-if="type === 'image' && (!hidden || preloadImage)"
class="image-attachment"
:class="{'hidden': hidden && preloadImage }"
:href="attachment.url"
target="_blank"
@click="openModal"
>
<StillImage
class="image"
:referrerpolicy="referrerpolicy"
:mimetype="attachment.mimetype"
:src="attachment.large_thumb_url || attachment.url"
:image-load-handler="onImageLoad"
:alt="attachment.description"
/>
</a>
<a
v-if="type === 'video' && !hidden"
class="video-container"
:class="{'small': isSmall}"
:href="allowPlay ? undefined : attachment.url"
@click="openModal"
>
<VideoAttachment
class="video"
:attachment="attachment"
:controls="allowPlay"
@play="$emit('play')"
@pause="$emit('pause')"
/>
<FAIcon
v-if="!allowPlay"
class="play-icon"
icon="play-circle"
/>
</a>
<audio
v-if="type === 'audio'"
:src="attachment.url"
:alt="attachment.description"
:title="attachment.description"
controls
@play="$emit('play')"
@pause="$emit('pause')"
/>
<div
v-if="type === 'html' && attachment.oembed"
class="oembed"
@click.prevent="linkClicked"
v-show="!isEmpty"
class="attachment-wrapper"
>
<div
v-if="attachment.thumb_url"
class="image"
<a
v-if="hidden"
class="image-container"
:href="attachment.url"
:alt="attachment.description"
:title="attachment.description"
@click.prevent.stop="toggleHidden"
>
<img :src="attachment.thumb_url">
<img
:key="nsfwImage"
class="nsfw"
:src="nsfwImage"
>
<FAIcon
v-if="type === 'video'"
class="play-icon"
icon="play-circle"
/>
</a>
<div
v-if="!hidden"
class="attachment-buttons"
>
<button
v-if="type === 'flash' && flashLoaded"
class="button-unstyled attachment-button"
:title="$t('status.attachment_stop_flash')"
@click.prevent="stopFlash"
>
<FAIcon icon="stop" />
</button>
<button
v-if="attachment.description && size !== 'small' && !edit && type !== 'unknown'"
class="button-unstyled attachment-button"
:title="$t('status.show_attachment_description')"
@click.prevent="toggleDescription"
>
<FAIcon icon="align-right" />
</button>
<button
v-if="!useModal && type !== 'unknown'"
class="button-unstyled attachment-button"
:title="$t('status.show_attachment_in_modal')"
@click.prevent="openModalForce"
>
<FAIcon icon="search-plus" />
</button>
<button
v-if="nsfw && hideNsfwLocal"
class="button-unstyled attachment-button"
:title="$t('status.hide_attachment')"
@click.prevent="toggleHidden"
>
<FAIcon icon="times" />
</button>
<button
v-if="shiftUp"
class="button-unstyled attachment-button"
:title="$t('status.move_up')"
@click.prevent="onShiftUp"
>
<FAIcon icon="chevron-left" />
</button>
<button
v-if="shiftDn"
class="button-unstyled attachment-button"
:title="$t('status.move_down')"
@click.prevent="onShiftDn"
>
<FAIcon icon="chevron-right" />
</button>
<button
v-if="remove"
class="button-unstyled attachment-button"
:title="$t('status.remove_attachment')"
@click.prevent="onRemove"
>
<FAIcon icon="trash-alt" />
</button>
</div>
<div class="text">
<!-- eslint-disable vue/no-v-html -->
<h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
<div v-html="attachment.oembed.oembedHTML" />
<!-- eslint-enable vue/no-v-html -->
</div>
</div>
<Flash
v-if="type === 'flash'"
:src="attachment.large_thumb_url || attachment.url"
/>
<a
v-if="type === 'image' && (!hidden || preloadImage)"
class="image-container"
:class="{'-hidden': hidden && preloadImage }"
:href="attachment.url"
target="_blank"
@click.stop.prevent="openModal"
>
<StillImage
class="image"
:referrerpolicy="referrerpolicy"
:mimetype="attachment.mimetype"
:src="attachment.large_thumb_url || attachment.url"
:image-load-handler="onImageLoad"
:alt="attachment.description"
/>
</a>
<a
v-if="type === 'unknown' && !hidden"
class="placeholder-container"
:href="attachment.url"
target="_blank"
>
<FAIcon
size="5x"
:icon="placeholderIconClass"
/>
<p>
{{ localDescription }}
</p>
</a>
<component
:is="videoTag"
v-if="type === 'video' && !hidden"
class="video-container"
:class="{ 'button-unstyled': 'isModal' }"
:href="attachment.url"
@click.stop.prevent="openModal"
>
<VideoAttachment
class="video"
:attachment="attachment"
:controls="!useModal"
@play="$emit('play')"
@pause="$emit('pause')"
/>
<FAIcon
v-if="useModal"
class="play-icon"
icon="play-circle"
/>
</component>
<span
v-if="type === 'audio' && !hidden"
class="audio-container"
:href="attachment.url"
@click.stop.prevent="openModal"
>
<audio
v-if="type === 'audio'"
:src="attachment.url"
:alt="attachment.description"
:title="attachment.description"
controls
@play="$emit('play')"
@pause="$emit('pause')"
/>
</span>
<div
v-if="type === 'html' && attachment.oembed"
class="oembed-container"
@click.prevent="linkClicked"
>
<div
v-if="attachment.thumb_url"
class="image"
>
<img :src="attachment.thumb_url">
</div>
<div class="text">
<!-- eslint-disable vue/no-v-html -->
<h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
<div v-html="attachment.oembed.oembedHTML" />
<!-- eslint-enable vue/no-v-html -->
</div>
</div>
<span
v-if="type === 'flash' && !hidden"
class="flash-container"
:href="attachment.url"
@click.stop.prevent="openModal"
>
<Flash
ref="flash"
class="flash"
:src="attachment.large_thumb_url || attachment.url"
@playerOpened="setFlashLoaded(true)"
@playerClosed="setFlashLoaded(false)"
/>
</span>
</div>
<div
v-if="size !== 'hide' && !hideDescription && (edit || (localDescription && showDescription))"
class="description-container"
:class="{ '-static': !edit }"
>
<textarea
v-if="edit"
v-model="localDescription"
class="description-field"
:placeholder="$t('post_status.media_description')"
rows="1"
cols="1"
@input="resize"
/>
<p v-else>
{{ localDescription }}
</p>
</div>
</div>
</template>
<script src="./attachment.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.attachments {
display: flex;
flex-wrap: wrap;
.non-gallery {
max-width: 100%;
}
.placeholder {
display: inline-block;
padding: 0.3em 1em 0.3em 0;
color: $fallback--link;
color: var(--postLink, $fallback--link);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
svg {
color: inherit;
}
}
.nsfw-placeholder {
cursor: pointer;
&.loading {
cursor: progress;
}
}
.attachment {
position: relative;
margin-top: 0.5em;
align-self: flex-start;
line-height: 0;
border-style: solid;
border-width: 1px;
border-radius: $fallback--attachmentRadius;
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
overflow: hidden;
}
.non-gallery.attachment {
&.flash,
&.video {
flex: 1 0 40%;
}
.nsfw {
height: 260px;
}
.small {
height: 120px;
flex-grow: 0;
}
.video {
height: 260px;
display: flex;
}
video {
max-height: 100%;
object-fit: contain;
}
}
.fullwidth {
flex-basis: 100%;
}
// fixes small gap below video
&.video {
line-height: 0;
}
.video-container {
display: flex;
max-height: 100%;
}
.video {
width: 100%;
height: 100%;
}
.play-icon {
position: absolute;
font-size: 64px;
top: calc(50% - 32px);
left: calc(50% - 32px);
color: rgba(255, 255, 255, 0.75);
text-shadow: 0 0 2px rgba(0, 0, 0, 0.4);
}
.play-icon::before {
margin: 0;
}
&.html {
flex-basis: 90%;
width: 100%;
display: flex;
}
.hider {
position: absolute;
right: 0;
margin: 10px;
padding: 0;
z-index: 4;
border-radius: $fallback--tooltipRadius;
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
text-align: center;
width: 2em;
height: 2em;
font-size: 1.25em;
// TODO: theming? hard to theme with unknown background image color
background: rgba(230, 230, 230, 0.7);
.svg-inline--fa {
color: rgba(0, 0, 0, 0.6);
}
&:hover .svg-inline--fa {
color: rgba(0, 0, 0, 0.9);
}
}
video {
z-index: 0;
}
audio {
width: 100%;
}
img.media-upload {
line-height: 0;
max-height: 200px;
max-width: 100%;
}
.oembed {
line-height: 1.2em;
flex: 1 0 100%;
width: 100%;
margin-right: 15px;
display: flex;
img {
width: 100%;
}
.image {
flex: 1;
img {
border: 0px;
border-radius: 5px;
height: 100%;
object-fit: cover;
}
}
.text {
flex: 2;
margin: 8px;
word-break: break-all;
h1 {
font-size: 14px;
margin: 0px;
}
}
}
.image-attachment {
&,
& .image {
width: 100%;
height: 100%;
}
&.hidden {
display: none;
}
.nsfw {
object-fit: cover;
width: 100%;
height: 100%;
}
img {
image-orientation: from-image; // NOTE: only FF supports this
}
}
}
</style>
<style src="./attachment.scss" lang="scss"></style>

View file

@ -1,3 +1,4 @@
import { h, resolveComponent } from 'vue'
import LoginForm from '../login_form/login_form.vue'
import MFARecoveryForm from '../mfa_form/recovery_form.vue'
import MFATOTPForm from '../mfa_form/totp_form.vue'
@ -5,8 +6,8 @@ import { mapGetters } from 'vuex'
const AuthForm = {
name: 'AuthForm',
render (createElement) {
return createElement('component', { is: this.authForm })
render () {
return h(resolveComponent(this.authForm))
},
computed: {
authForm () {

View file

@ -1,5 +1,6 @@
import UserCard from '../user_card/user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const BasicUserCard = {
@ -13,7 +14,8 @@ const BasicUserCard = {
},
components: {
UserCard,
UserAvatar
UserAvatar,
RichContent
},
methods: {
toggleUserExpanded () {

View file

@ -4,7 +4,7 @@
<UserAvatar
class="avatar"
:user="user"
@click.prevent.native="toggleUserExpanded"
@click.prevent="toggleUserExpanded"
/>
</router-link>
<div
@ -25,17 +25,11 @@
:title="user.name"
class="basic-user-card-user-name"
>
<!-- eslint-disable vue/no-v-html -->
<span
v-if="user.name_html"
<RichContent
class="basic-user-card-user-name-value"
v-html="user.name_html"
:html="user.name"
:emoji="user.emoji"
/>
<!-- eslint-enable vue/no-v-html -->
<span
v-else
class="basic-user-card-user-name-value"
>{{ user.name }}</span>
</div>
<div>
<router-link

View file

@ -9,7 +9,7 @@ const Bookmarks = {
components: {
Timeline
},
destroyed () {
unmounted () {
this.$store.commit('clearTimeline', { timeline: 'bookmarks' })
}
}

View file

@ -6,7 +6,7 @@ import PostStatusForm from '../post_status_form/post_status_form.vue'
import ChatTitle from '../chat_title/chat_title.vue'
import chatService from '../../services/chat_service/chat_service.js'
import { promiseInterval } from '../../services/promise_interval/promise_interval.js'
import { getScrollPosition, getNewTopPosition, isBottomedOut, scrollableContainerHeight, isScrollable } from './chat_layout_utils.js'
import { getScrollPosition, getNewTopPosition, isBottomedOut, isScrollable } from './chat_layout_utils.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown,
@ -20,7 +20,7 @@ library.add(
)
const BOTTOMED_OUT_OFFSET = 10
const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 150
const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 10
const SAFE_RESIZE_TIME_OFFSET = 100
const MARK_AS_READ_DELAY = 1500
const MAX_RETRIES = 10
@ -43,7 +43,7 @@ const Chat = {
},
created () {
this.startFetching()
window.addEventListener('resize', this.handleLayoutChange)
window.addEventListener('resize', this.handleResize)
},
mounted () {
window.addEventListener('scroll', this.handleScroll)
@ -52,15 +52,11 @@ const Chat = {
}
this.$nextTick(() => {
this.updateScrollableContainerHeight()
this.handleResize()
})
this.setChatLayout()
},
destroyed () {
unmounted () {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleLayoutChange)
this.unsetChatLayout()
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
this.$store.dispatch('clearCurrentChat')
},
@ -96,8 +92,7 @@ const Chat = {
...mapState({
backendInteractor: state => state.api.backendInteractor,
mastoUserSocketStatus: state => state.api.mastoUserSocketStatus,
mobileLayout: state => state.interface.mobileLayout,
layoutHeight: state => state.interface.layoutHeight,
mobileLayout: state => state.interface.layoutType === 'mobile',
currentUser: state => state.users.currentUser
})
},
@ -115,9 +110,6 @@ const Chat = {
'$route': function () {
this.startFetching()
},
layoutHeight () {
this.handleResize({ expand: true })
},
mastoUserSocketStatus (newValue) {
if (newValue === WSConnectionStatus.JOINED) {
this.fetchChat({ isFirstFetch: true })
@ -132,7 +124,6 @@ const Chat = {
onFilesDropped () {
this.$nextTick(() => {
this.handleResize()
this.updateScrollableContainerHeight()
})
},
handleVisibilityChange () {
@ -142,43 +133,7 @@ const Chat = {
}
})
},
setChatLayout () {
// This is a hacky way to adjust the global layout to the mobile chat (without modifying the rest of the app).
// This layout prevents empty spaces from being visible at the bottom
// of the chat on iOS Safari (`safe-area-inset`) when
// - the on-screen keyboard appears and the user starts typing
// - the user selects the text inside the input area
// - the user selects and deletes the text that is multiple lines long
// TODO: unify the chat layout with the global layout.
let html = document.querySelector('html')
if (html) {
html.classList.add('chat-layout')
}
this.$nextTick(() => {
this.updateScrollableContainerHeight()
})
},
unsetChatLayout () {
let html = document.querySelector('html')
if (html) {
html.classList.remove('chat-layout')
}
},
handleLayoutChange () {
this.$nextTick(() => {
this.updateScrollableContainerHeight()
this.scrollDown()
})
},
// Ensures the proper position of the posting form in the mobile layout (the mobile browser panel does not overlap or hide it)
updateScrollableContainerHeight () {
const header = this.$refs.header
const footer = this.$refs.footer
const inner = this.mobileLayout ? window.document.body : this.$refs.inner
this.scrollableContainerHeight = scrollableContainerHeight(inner, header, footer) + 'px'
},
// Preserves the scroll position when OSK appears or the posting form changes its height.
// "Sticks" scroll to bottom instead of top, helps with OSK resizing the viewport
handleResize (opts = {}) {
const { expand = false, delayed = false } = opts
@ -190,29 +145,20 @@ const Chat = {
}
this.$nextTick(() => {
this.updateScrollableContainerHeight()
const { offsetHeight = undefined } = this.lastScrollPosition
this.lastScrollPosition = getScrollPosition(this.$refs.scrollable)
const { offsetHeight = undefined } = getScrollPosition()
const diff = this.lastScrollPosition.offsetHeight - offsetHeight
if (diff < 0 || (!this.bottomedOut() && expand)) {
if (diff !== 0 || (!this.bottomedOut() && expand)) {
this.$nextTick(() => {
this.updateScrollableContainerHeight()
this.$refs.scrollable.scrollTo({
top: this.$refs.scrollable.scrollTop - diff,
left: 0
})
window.scrollTo({ top: window.scrollY + diff })
})
}
this.lastScrollPosition = getScrollPosition()
})
},
scrollDown (options = {}) {
const { behavior = 'auto', forceRead = false } = options
const scrollable = this.$refs.scrollable
if (!scrollable) { return }
this.$nextTick(() => {
scrollable.scrollTo({ top: scrollable.scrollHeight, left: 0, behavior })
window.scrollTo({ top: document.documentElement.scrollHeight, behavior })
})
if (forceRead) {
this.readChat()
@ -228,11 +174,10 @@ const Chat = {
})
},
bottomedOut (offset) {
return isBottomedOut(this.$refs.scrollable, offset)
return isBottomedOut(offset)
},
reachedTop () {
const scrollable = this.$refs.scrollable
return scrollable && scrollable.scrollTop <= 0
return window.scrollY <= 0
},
cullOlderCheck () {
window.setTimeout(() => {
@ -263,10 +208,9 @@ const Chat = {
}
}, 200),
handleScrollUp (positionBeforeLoading) {
const positionAfterLoading = getScrollPosition(this.$refs.scrollable)
this.$refs.scrollable.scrollTo({
top: getNewTopPosition(positionBeforeLoading, positionAfterLoading),
left: 0
const positionAfterLoading = getScrollPosition()
window.scrollTo({
top: getNewTopPosition(positionBeforeLoading, positionAfterLoading)
})
},
fetchChat ({ isFirstFetch = false, fetchLatest = false, maxId }) {
@ -285,22 +229,18 @@ const Chat = {
chatService.clear(chatMessageService)
}
const positionBeforeUpdate = getScrollPosition(this.$refs.scrollable)
const positionBeforeUpdate = getScrollPosition()
this.$store.dispatch('addChatMessages', { chatId, messages }).then(() => {
this.$nextTick(() => {
if (fetchOlderMessages) {
this.handleScrollUp(positionBeforeUpdate)
}
if (isFirstFetch) {
this.updateScrollableContainerHeight()
}
// In vertical screens, the first batch of fetched messages may not always take the
// full height of the scrollable container.
// If this is the case, we want to fetch the messages until the scrollable container
// is fully populated so that the user has the ability to scroll up and load the history.
if (!isScrollable(this.$refs.scrollable) && messages.length > 0) {
if (!isScrollable() && messages.length > 0) {
this.fetchChat({ maxId: this.currentChatMessageService.minId })
}
})
@ -336,9 +276,6 @@ const Chat = {
this.handleResize()
// When the posting form size changes because of a media attachment, we need an extra resize
// to account for the potential delay in the DOM update.
setTimeout(() => {
this.updateScrollableContainerHeight()
}, SAFE_RESIZE_TIME_OFFSET)
this.scrollDown({ forceRead: true })
})
},

View file

@ -1,28 +1,22 @@
.chat-view {
display: flex;
height: calc(100vh - 60px);
width: 100%;
.chat-title {
// prevents chat header jumping on when the user avatar loads
height: 28px;
}
height: 100%;
.chat-view-inner {
height: auto;
width: 100%;
overflow: visible;
display: flex;
margin: 0.5em 0.5em 0 0.5em;
}
.chat-view-body {
box-sizing: border-box;
background-color: var(--chatBg, $fallback--bg);
display: flex;
flex-direction: column;
width: 100%;
overflow: visible;
min-height: 100%;
min-height: calc(100vh - var(--navbar-height));
margin: 0 0 0 0;
border-radius: 10px 10px 0 0;
border-radius: var(--panelRadius, 10px) var(--panelRadius, 10px) 0 0;
@ -32,36 +26,32 @@
}
}
.scrollable-message-list {
.message-list {
padding: 0 0.8em;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
display: flex;
flex-direction: column;
justify-content: end;
}
.footer {
position: sticky;
bottom: 0;
background-color: $fallback--bg;
background-color: var(--bg, $fallback--bg);
z-index: 1;
}
.chat-view-heading {
align-items: center;
justify-content: space-between;
top: 50px;
display: flex;
z-index: 2;
position: sticky;
overflow: hidden;
grid-template-columns: auto minmax(50%, 1fr);
}
.go-back-button {
cursor: pointer;
width: 28px;
text-align: center;
padding: 0.6em;
margin: -0.6em 0.6em -0.6em -0.6em;
line-height: 1;
height: 100%;
align-self: start;
width: var(--__panel-heading-height-inner);
}
.jump-to-bottom-button {
@ -115,56 +105,4 @@
}
}
}
@media all and (max-width: 800px) {
height: 100%;
overflow: hidden;
.chat-view-inner {
overflow: hidden;
height: 100%;
margin-top: 0;
margin-left: 0;
margin-right: 0;
}
.chat-view-body {
display: flex;
min-height: auto;
overflow: hidden;
height: 100%;
margin: 0;
border-radius: 0;
}
.chat-view-heading {
box-sizing: border-box;
position: static;
z-index: 9999;
top: 0;
margin-top: 0;
border-radius: 0;
/* This practically overlays the panel heading color over panel background
* color. This is needed because we allow transparent panel background and
* it doesn't work well in this "disjointed panel header" case
*/
background:
linear-gradient(to top, var(--panel), var(--panel)),
linear-gradient(to top, var(--bg), var(--bg));
height: 50px;
}
.scrollable-message-list {
display: unset;
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
}
.footer {
position: sticky;
bottom: auto;
}
}
}

View file

@ -2,23 +2,22 @@
<div class="chat-view">
<div class="chat-view-inner">
<div
id="nav"
ref="inner"
class="panel-default panel chat-view-body"
>
<div
ref="header"
class="panel-heading chat-view-heading mobile-hidden"
class="panel-heading -sticky chat-view-heading"
>
<a
class="go-back-button"
<button
class="button-unstyled go-back-button"
@click="goBack"
>
<FAIcon
size="lg"
icon="chevron-left"
/>
</a>
</button>
<div class="title text-center">
<ChatTitle
:user="recipient"
@ -26,73 +25,69 @@
/>
</div>
</div>
<template>
<div
ref="scrollable"
class="scrollable-message-list"
:style="{ height: scrollableContainerHeight }"
@scroll="handleScroll"
>
<template v-if="!errorLoadingChat">
<ChatMessage
v-for="chatViewItem in chatViewItems"
:key="chatViewItem.id"
:author="recipient"
:chat-view-item="chatViewItem"
:hovered-message-chain="chatViewItem.messageChainId === hoveredMessageChainId"
@hover="onMessageHover"
/>
</template>
<div
v-else
class="chat-loading-error"
>
<div class="alert error">
{{ $t('chats.error_loading_chat') }}
</div>
</div>
</div>
<div
ref="footer"
class="panel-body footer"
>
<div
class="jump-to-bottom-button"
:class="{ 'visible': jumpToBottomButtonVisible }"
@click="scrollDown({ behavior: 'smooth' })"
>
<span>
<FAIcon icon="chevron-down" />
<div
v-if="newMessageCount"
class="badge badge-notification unread-chat-count unread-message-count"
>
{{ newMessageCount }}
</div>
</span>
</div>
<PostStatusForm
:disable-subject="true"
:disable-scope-selector="true"
:disable-notice="true"
:disable-lock-warning="true"
:disable-polls="true"
:disable-sensitivity-checkbox="true"
:disable-submit="errorLoadingChat || !currentChat"
:disable-preview="true"
:optimistic-posting="true"
:post-handler="sendMessage"
:submit-on-enter="!mobileLayout"
:preserve-focus="!mobileLayout"
:auto-focus="!mobileLayout"
:placeholder="formPlaceholder"
:file-limit="1"
max-height="160"
emoji-picker-placement="top"
@resize="handleResize"
<div
class="message-list"
:style="{ height: scrollableContainerHeight }"
>
<template v-if="!errorLoadingChat">
<ChatMessage
v-for="chatViewItem in chatViewItems"
:key="chatViewItem.id"
:author="recipient"
:chat-view-item="chatViewItem"
:hovered-message-chain="chatViewItem.messageChainId === hoveredMessageChainId"
@hover="onMessageHover"
/>
</template>
<div
v-else
class="chat-loading-error"
>
<div class="alert error">
{{ $t('chats.error_loading_chat') }}
</div>
</div>
</template>
</div>
<div
ref="footer"
class="panel-body footer"
>
<div
class="jump-to-bottom-button"
:class="{ 'visible': jumpToBottomButtonVisible }"
@click="scrollDown({ behavior: 'smooth' })"
>
<span>
<FAIcon icon="chevron-down" />
<div
v-if="newMessageCount"
class="badge badge-notification unread-chat-count unread-message-count"
>
{{ newMessageCount }}
</div>
</span>
</div>
<PostStatusForm
:disable-subject="true"
:disable-scope-selector="true"
:disable-notice="true"
:disable-lock-warning="true"
:disable-polls="true"
:disable-sensitivity-checkbox="true"
:disable-submit="errorLoadingChat || !currentChat"
:disable-preview="true"
:optimistic-posting="true"
:post-handler="sendMessage"
:submit-on-enter="!mobileLayout"
:preserve-focus="!mobileLayout"
:auto-focus="!mobileLayout"
:placeholder="formPlaceholder"
:file-limit="1"
max-height="160"
emoji-picker-placement="top"
@resize="handleResize"
/>
</div>
</div>
</div>
</div>

View file

@ -1,9 +1,9 @@
// Captures a scroll position
export const getScrollPosition = (el) => {
export const getScrollPosition = () => {
return {
scrollTop: el.scrollTop,
scrollHeight: el.scrollHeight,
offsetHeight: el.offsetHeight
scrollTop: window.scrollY,
scrollHeight: document.documentElement.scrollHeight,
offsetHeight: window.innerHeight
}
}
@ -13,21 +13,12 @@ export const getNewTopPosition = (previousPosition, newPosition) => {
return previousPosition.scrollTop + (newPosition.scrollHeight - previousPosition.scrollHeight)
}
export const isBottomedOut = (el, offset = 0) => {
if (!el) { return }
const scrollHeight = el.scrollTop + offset
const totalHeight = el.scrollHeight - el.offsetHeight
export const isBottomedOut = (offset = 0) => {
const scrollHeight = window.scrollY + offset
const totalHeight = document.documentElement.scrollHeight - window.innerHeight
return totalHeight <= scrollHeight
}
// Height of the scrollable container. The dynamic height is needed to ensure the mobile browser panel doesn't overlap or hide the posting form.
export const scrollableContainerHeight = (inner, header, footer) => {
return inner.offsetHeight - header.clientHeight - footer.clientHeight
}
// Returns whether or not the scrollbar is visible.
export const isScrollable = (el) => {
if (!el) return
return el.scrollHeight > el.clientHeight
export const isScrollable = () => {
return document.documentElement.scrollHeight > window.innerHeight
}

View file

@ -6,7 +6,7 @@
v-else
class="chat-list panel panel-default"
>
<div class="panel-heading">
<div class="panel-heading -sticky">
<span class="title">
{{ $t("chats.chats") }}
</span>

View file

@ -1,5 +1,5 @@
import { mapState } from 'vuex'
import StatusContent from '../status_content/status_content.vue'
import StatusBody from '../status_content/status_content.vue'
import fileType from 'src/services/file_type/file_type.service'
import UserAvatar from '../user_avatar/user_avatar.vue'
import AvatarList from '../avatar_list/avatar_list.vue'
@ -16,7 +16,7 @@ const ChatListItem = {
AvatarList,
Timeago,
ChatTitle,
StatusContent
StatusBody
},
computed: {
...mapState({
@ -38,12 +38,14 @@ const ChatListItem = {
},
messageForStatusContent () {
const message = this.chat.lastMessage
const messageEmojis = message ? message.emojis : []
const isYou = message && message.account_id === this.currentUser.id
const content = message ? (this.attachmentInfo || message.content) : ''
const messagePreview = isYou ? `<i>${this.$t('chats.you')}</i> ${content}` : content
return {
summary: '',
statusnet_html: messagePreview,
emojis: messageEmojis,
raw_html: messagePreview,
text: messagePreview,
attachments: []
}

View file

@ -43,7 +43,7 @@
white-space: nowrap;
overflow: hidden;
flex-shrink: 1;
line-height: 1.4em;
line-height: var(--post-line-height);
}
.chat-preview {
@ -77,18 +77,15 @@
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
}
.StatusContent {
img.emoji {
width: 1.4em;
height: 1.4em;
}
.chat-preview-body {
--emoji-size: 1.4em;
}
.time-wrapper {
line-height: 1.4em;
line-height: var(--post-line-height);
}
.single-line {
.chat-preview-body {
padding-right: 1em;
}
}

View file

@ -29,7 +29,8 @@
</div>
</div>
<div class="chat-preview">
<StatusContent
<StatusBody
class="chat-preview-body"
:status="messageForStatusContent"
:single-line="true"
/>

View file

@ -27,6 +27,7 @@ const ChatMessage = {
'chatViewItem',
'hoveredMessageChain'
],
emits: ['hover'],
components: {
Popover,
Attachment,
@ -57,8 +58,9 @@ const ChatMessage = {
messageForStatusContent () {
return {
summary: '',
statusnet_html: this.message.content,
text: this.message.content,
emojis: this.message.emojis,
raw_html: this.message.content || '',
text: this.message.content || '',
attachments: this.message.attachments
}
},

View file

@ -1,6 +1,7 @@
@import '../../_variables.scss';
.chat-message-wrapper {
&.hovered-message-chain {
.animated.Avatar {
canvas {
@ -40,6 +41,12 @@
.chat-message {
display: flex;
padding-bottom: 0.5em;
.status-body:hover {
--_still-image-img-visibility: visible;
--_still-image-canvas-visibility: hidden;
--_still-image-label-visibility: hidden;
}
}
.avatar-wrapper {
@ -62,10 +69,6 @@
&.with-media {
width: 100%;
.gallery-row {
overflow: hidden;
}
.status {
width: 100%;
}
@ -89,8 +92,9 @@
}
.without-attachment {
.status-content {
&::after {
.message-content {
// TODO figure out how to do it properly
.RichContent::after {
margin-right: 5.4em;
content: " ";
display: inline-block;
@ -162,6 +166,7 @@
.visible {
opacity: 1;
}
}
.chat-message-date-separator {

View file

@ -71,6 +71,7 @@
</Popover>
</div>
<StatusContent
class="message-content"
:status="messageForStatusContent"
:full-content="true"
>

View file

@ -22,10 +22,10 @@
}
.go-back-button {
cursor: pointer;
width: 28px;
text-align: center;
padding: 0.6em;
margin: -0.6em 0.6em -0.6em -0.6em;
line-height: 1;
height: 100%;
align-self: start;
width: var(--__panel-heading-height-inner);
}
}

View file

@ -1,21 +1,20 @@
<template>
<div
id="nav"
class="panel-default panel chat-new"
>
<div
ref="header"
class="panel-heading"
>
<a
class="go-back-button"
<button
class="button-unstyled go-back-button"
@click="goBack"
>
<FAIcon
size="lg"
icon="chevron-left"
/>
</a>
</button>
</div>
<div class="input-wrap">
<div class="input-search">

View file

@ -1,11 +1,12 @@
import Vue from 'vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import UserAvatar from '../user_avatar/user_avatar.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
export default Vue.component('chat-title', {
export default {
name: 'ChatTitle',
components: {
UserAvatar
UserAvatar,
RichContent
},
props: [
'user', 'withAvatar'
@ -23,4 +24,4 @@ export default Vue.component('chat-title', {
return generateProfileLink(user.id, user.screen_name)
}
}
})
}

View file

@ -1,25 +1,26 @@
<template>
<!-- eslint-disable vue/no-v-html -->
<div
class="chat-title"
:title="title"
>
<router-link
v-if="withAvatar && user"
class="avatar-container"
:to="getUserProfileLink(user)"
>
<UserAvatar
class="titlebar-avatar"
:user="user"
width="23px"
height="23px"
/>
</router-link>
<span
<RichContent
v-if="user"
class="username"
v-html="htmlTitle"
:title="'@'+(user && user.screen_name_ui)"
:html="htmlTitle"
:emoji="user.emoji || []"
/>
</div>
<!-- eslint-enable vue/no-v-html -->
</template>
<script src="./chat_title.js"></script>
@ -32,7 +33,8 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
align-items: center;
--emoji-size: 14px;
.username {
max-width: 100%;
@ -41,21 +43,17 @@
display: inline;
word-wrap: break-word;
overflow: hidden;
text-overflow: ellipsis;
.emoji {
width: 14px;
height: 14px;
vertical-align: middle;
object-fit: contain
}
}
.Avatar {
width: 23px;
height: 23px;
margin-right: 0.5em;
.avatar-container {
align-self: center;
line-height: 1;
}
.titlebar-avatar {
margin-right: 0.5em;
height: 1.5em;
width: 1.5em;
border-radius: $fallback--avatarAltRadius;
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);

View file

@ -6,9 +6,9 @@
<input
type="checkbox"
:disabled="disabled"
:checked="checked"
:indeterminate.prop="indeterminate"
@change="$emit('change', $event.target.checked)"
:checked="modelValue"
:indeterminate="indeterminate"
@change="$emit('update:modelValue', $event.target.checked)"
>
<i class="checkbox-indicator" />
<span
@ -22,12 +22,9 @@
<script>
export default {
model: {
prop: 'checked',
event: 'change'
},
emits: ['update:modelValue'],
props: [
'checked',
'modelValue',
'indeterminate',
'disabled'
]

View file

@ -11,28 +11,28 @@
</label>
<Checkbox
v-if="typeof fallback !== 'undefined' && showOptionalTickbox"
:checked="present"
:model-value="present"
:disabled="disabled"
class="opt"
@change="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
@update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
/>
<div class="input color-input-field">
<input
:id="name + '-t'"
class="textColor unstyled"
type="text"
:value="value || fallback"
:value="modelValue || fallback"
:disabled="!present || disabled"
@input="$emit('input', $event.target.value)"
@input="$emit('update:modelValue', $event.target.value)"
>
<input
v-if="validColor"
:id="name"
class="nativeColor unstyled"
type="color"
:value="value || fallback"
:value="modelValue || fallback"
:disabled="!present || disabled"
@input="$emit('input', $event.target.value)"
@input="$emit('update:modelValue', $event.target.value)"
>
<div
v-if="transparentColor"
@ -67,7 +67,7 @@ export default {
},
// Color value, should be required but vue cannot tell the difference
// between "property missing" and "property set to undefined"
value: {
modelValue: {
required: false,
type: String,
default: undefined
@ -91,18 +91,19 @@ export default {
default: true
}
},
emits: ['update:modelValue'],
computed: {
present () {
return typeof this.value !== 'undefined'
return typeof this.modelValue !== 'undefined'
},
validColor () {
return hex2rgb(this.value || this.fallback)
return hex2rgb(this.modelValue || this.fallback)
},
transparentColor () {
return this.value === 'transparent'
return this.modelValue === 'transparent'
},
computedColor () {
return this.value && this.value.startsWith('--')
return this.modelValue && this.modelValue.startsWith('--')
}
}
}

View file

@ -1,5 +1,19 @@
import { reduce, filter, findIndex, clone, get } from 'lodash'
import Status from '../status/status.vue'
import ThreadTree from '../thread_tree/thread_tree.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleDown,
faAngleDoubleLeft,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons'
library.add(
faAngleDoubleDown,
faAngleDoubleLeft,
faChevronLeft
)
const sortById = (a, b) => {
const idA = a.type === 'retweet' ? a.retweeted_status.id : a.id
@ -35,7 +49,10 @@ const conversation = {
data () {
return {
highlight: null,
expanded: false
expanded: false,
threadDisplayStatusObject: {}, // id => 'showing' | 'hidden'
statusContentPropertiesObject: {},
inlineDivePosition: null
}
},
props: [
@ -53,12 +70,50 @@ const conversation = {
}
},
computed: {
hideStatus () {
if (this.$refs.statusComponent && this.$refs.statusComponent[0]) {
return this.virtualHidden && this.$refs.statusComponent[0].suspendable
} else {
return this.virtualHidden
maxDepthToShowByDefault () {
// maxDepthInThread = max number of depths that is *visible*
// since our depth starts with 0 and "showing" means "showing children"
// there is a -2 here
const maxDepth = this.$store.getters.mergedConfig.maxDepthInThread - 2
return maxDepth >= 1 ? maxDepth : 1
},
displayStyle () {
return this.$store.getters.mergedConfig.conversationDisplay
},
isTreeView () {
return !this.isLinearView
},
treeViewIsSimple () {
return !this.$store.getters.mergedConfig.conversationTreeAdvanced
},
isLinearView () {
return this.displayStyle === 'linear'
},
shouldFadeAncestors () {
return this.$store.getters.mergedConfig.conversationTreeFadeAncestors
},
otherRepliesButtonPosition () {
return this.$store.getters.mergedConfig.conversationOtherRepliesButton
},
showOtherRepliesButtonBelowStatus () {
return this.otherRepliesButtonPosition === 'below'
},
showOtherRepliesButtonInsideStatus () {
return this.otherRepliesButtonPosition === 'inside'
},
suspendable () {
if (this.isTreeView) {
return Object.entries(this.statusContentProperties)
.every(([k, prop]) => !prop.replying && prop.mediaPlaying.length === 0)
}
if (this.$refs.statusComponent && this.$refs.statusComponent[0]) {
return this.$refs.statusComponent.every(s => s.suspendable)
} else {
return true
}
},
hideStatus () {
return this.virtualHidden && this.suspendable
},
status () {
return this.$store.state.statuses.allStatusesObject[this.statusId]
@ -90,6 +145,121 @@ const conversation = {
return sortAndFilterConversation(conversation, this.status)
},
statusMap () {
return this.conversation.reduce((res, s) => {
res[s.id] = s
return res
}, {})
},
threadTree () {
const reverseLookupTable = this.conversation.reduce((table, status, index) => {
table[status.id] = index
return table
}, {})
const threads = this.conversation.reduce((a, cur) => {
const id = cur.id
a.forest[id] = this.getReplies(id)
.map(s => s.id)
return a
}, {
forest: {}
})
const walk = (forest, topLevel, depth = 0, processed = {}) => topLevel.map(id => {
if (processed[id]) {
return []
}
processed[id] = true
return [{
status: this.conversation[reverseLookupTable[id]],
id,
depth
}, walk(forest, forest[id], depth + 1, processed)].reduce((a, b) => a.concat(b), [])
}).reduce((a, b) => a.concat(b), [])
const linearized = walk(threads.forest, this.topLevel.map(k => k.id))
return linearized
},
replyIds () {
return this.conversation.map(k => k.id)
.reduce((res, id) => {
res[id] = (this.replies[id] || []).map(k => k.id)
return res
}, {})
},
totalReplyCount () {
const sizes = {}
const subTreeSizeFor = (id) => {
if (sizes[id]) {
return sizes[id]
}
sizes[id] = 1 + this.replyIds[id].map(cid => subTreeSizeFor(cid)).reduce((a, b) => a + b, 0)
return sizes[id]
}
this.conversation.map(k => k.id).map(subTreeSizeFor)
return Object.keys(sizes).reduce((res, id) => {
res[id] = sizes[id] - 1 // exclude itself
return res
}, {})
},
totalReplyDepth () {
const depths = {}
const subTreeDepthFor = (id) => {
if (depths[id]) {
return depths[id]
}
depths[id] = 1 + this.replyIds[id].map(cid => subTreeDepthFor(cid)).reduce((a, b) => a > b ? a : b, 0)
return depths[id]
}
this.conversation.map(k => k.id).map(subTreeDepthFor)
return Object.keys(depths).reduce((res, id) => {
res[id] = depths[id] - 1 // exclude itself
return res
}, {})
},
depths () {
return this.threadTree.reduce((a, k) => {
a[k.id] = k.depth
return a
}, {})
},
topLevel () {
const topLevel = this.conversation.reduce((tl, cur) =>
tl.filter(k => this.getReplies(cur.id).map(v => v.id).indexOf(k.id) === -1), this.conversation)
return topLevel
},
otherTopLevelCount () {
return this.topLevel.length - 1
},
showingTopLevel () {
if (this.canDive && this.diveRoot) {
return [this.statusMap[this.diveRoot]]
}
return this.topLevel
},
diveRoot () {
const statusId = this.inlineDivePosition || this.statusId
const isTopLevel = !this.parentOf(statusId)
return isTopLevel ? null : statusId
},
diveDepth () {
return this.canDive && this.diveRoot ? this.depths[this.diveRoot] : 0
},
diveMode () {
return this.canDive && !!this.diveRoot
},
shouldShowAllConversationButton () {
// The "show all conversation" button tells the user that there exist
// other toplevel statuses, so do not show it if there is only a single root
return this.isTreeView && this.isExpanded && this.diveMode && this.topLevel.length > 1
},
shouldShowAncestors () {
return this.isTreeView && this.isExpanded && this.ancestorsOf(this.diveRoot).length
},
replies () {
let i = 1
// eslint-disable-next-line camelcase
@ -109,15 +279,71 @@ const conversation = {
}, {})
},
isExpanded () {
return this.expanded || this.isPage
return !!(this.expanded || this.isPage)
},
hiddenStyle () {
const height = (this.status && this.status.virtualHeight) || '120px'
return this.virtualHidden ? { height } : {}
},
threadDisplayStatus () {
return this.conversation.reduce((a, k) => {
const id = k.id
const depth = this.depths[id]
const status = (() => {
if (this.threadDisplayStatusObject[id]) {
return this.threadDisplayStatusObject[id]
}
if ((depth - this.diveDepth) <= this.maxDepthToShowByDefault) {
return 'showing'
} else {
return 'hidden'
}
})()
a[id] = status
return a
}, {})
},
statusContentProperties () {
return this.conversation.reduce((a, k) => {
const id = k.id
const props = (() => {
const def = {
showingTall: false,
expandingSubject: false,
showingLongSubject: false,
isReplying: false,
mediaPlaying: []
}
if (this.statusContentPropertiesObject[id]) {
return {
...def,
...this.statusContentPropertiesObject[id]
}
}
return def
})()
a[id] = props
return a
}, {})
},
canDive () {
return this.isTreeView && this.isExpanded
},
focused () {
return (id) => {
return (this.isExpanded) && id === this.highlight
}
},
maybeHighlight () {
return this.isExpanded ? this.highlight : null
}
},
components: {
Status
Status,
ThreadTree
},
watch: {
statusId (newVal, oldVal) {
@ -132,6 +358,8 @@ const conversation = {
expanded (value) {
if (value) {
this.fetchConversation()
} else {
this.resetDisplayState()
}
},
virtualHidden (value) {
@ -161,8 +389,8 @@ const conversation = {
getReplies (id) {
return this.replies[id] || []
},
focused (id) {
return (this.isExpanded) && id === this.statusId
getHighlight () {
return this.isExpanded ? this.highlight : null
},
setHighlight (id) {
if (!id) return
@ -170,15 +398,139 @@ const conversation = {
this.$store.dispatch('fetchFavsAndRepeats', id)
this.$store.dispatch('fetchEmojiReactionsBy', id)
},
getHighlight () {
return this.isExpanded ? this.highlight : null
},
toggleExpanded () {
this.expanded = !this.expanded
},
getConversationId (statusId) {
const status = this.$store.state.statuses.allStatusesObject[statusId]
return get(status, 'retweeted_status.statusnet_conversation_id', get(status, 'statusnet_conversation_id'))
},
setThreadDisplay (id, nextStatus) {
this.threadDisplayStatusObject = {
...this.threadDisplayStatusObject,
[id]: nextStatus
}
},
toggleThreadDisplay (id) {
const curStatus = this.threadDisplayStatus[id]
const nextStatus = curStatus === 'showing' ? 'hidden' : 'showing'
this.setThreadDisplay(id, nextStatus)
},
setThreadDisplayRecursively (id, nextStatus) {
this.setThreadDisplay(id, nextStatus)
this.getReplies(id).map(k => k.id).map(id => this.setThreadDisplayRecursively(id, nextStatus))
},
showThreadRecursively (id) {
this.setThreadDisplayRecursively(id, 'showing')
},
setStatusContentProperty (id, name, value) {
this.statusContentPropertiesObject = {
...this.statusContentPropertiesObject,
[id]: {
...this.statusContentPropertiesObject[id],
[name]: value
}
}
},
toggleStatusContentProperty (id, name) {
this.setStatusContentProperty(id, name, !this.statusContentProperties[id][name])
},
leastVisibleAncestor (id) {
let cur = id
let parent = this.parentOf(cur)
while (cur) {
// if the parent is showing it means cur is visible
if (this.threadDisplayStatus[parent] === 'showing') {
return cur
}
parent = this.parentOf(parent)
cur = this.parentOf(cur)
}
// nothing found, fall back to toplevel
return this.topLevel[0] ? this.topLevel[0].id : undefined
},
diveIntoStatus (id, preventScroll) {
this.tryScrollTo(id)
},
diveToTopLevel () {
this.tryScrollTo(this.topLevelAncestorOrSelfId(this.diveRoot) || this.topLevel[0].id)
},
// only used when we are not on a page
undive () {
this.inlineDivePosition = null
this.setHighlight(this.statusId)
},
tryScrollTo (id) {
if (!id) {
return
}
if (this.isPage) {
// set statusId
this.$router.push({ name: 'conversation', params: { id } })
} else {
this.inlineDivePosition = id
}
// Because the conversation can be unmounted when out of sight
// and mounted again when it comes into sight,
// the `mounted` or `created` function in `status` should not
// contain scrolling calls, as we do not want the page to jump
// when we scroll with an expanded conversation.
//
// Now the method is to rely solely on the `highlight` watcher
// in `status` components.
// In linear views, all statuses are rendered at all times, but
// in tree views, it is possible that a change in active status
// removes and adds status components (e.g. an originally child
// status becomes an ancestor status, and thus they will be
// different).
// Here, let the components be rendered first, in order to trigger
// the `highlight` watcher.
this.$nextTick(() => {
this.setHighlight(id)
})
},
goToCurrent () {
this.tryScrollTo(this.diveRoot || this.topLevel[0].id)
},
statusById (id) {
return this.statusMap[id]
},
parentOf (id) {
const status = this.statusById(id)
if (!status) {
return undefined
}
const { in_reply_to_status_id: parentId } = status
if (!this.statusMap[parentId]) {
return undefined
}
return parentId
},
parentOrSelf (id) {
return this.parentOf(id) || id
},
// Ancestors of some status, from top to bottom
ancestorsOf (id) {
const ancestors = []
let cur = this.parentOf(id)
while (cur) {
ancestors.unshift(this.statusMap[cur])
cur = this.parentOf(cur)
}
return ancestors
},
topLevelAncestorOrSelfId (id) {
let cur = id
let parent = this.parentOf(id)
while (parent) {
cur = this.parentOf(cur)
parent = this.parentOf(parent)
}
return cur
},
resetDisplayState () {
this.undive()
this.threadDisplayStatusObject = {}
}
}
}

View file

@ -7,7 +7,7 @@
>
<div
v-if="isExpanded"
class="panel-heading conversation-heading"
class="panel-heading conversation-heading -sticky"
>
<span class="title"> {{ $t('timeline.conversation') }} </span>
<button
@ -18,24 +18,176 @@
{{ $t('timeline.collapse') }}
</button>
</div>
<status
v-for="status in conversation"
:key="status.id"
ref="statusComponent"
:inline-expanded="collapsable && isExpanded"
:statusoid="status"
:expandable="!isExpanded"
:show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
:focused="focused(status.id)"
:in-conversation="isExpanded"
:highlight="getHighlight()"
:replies="getReplies(status.id)"
:in-profile="inProfile"
:profile-user-id="profileUserId"
class="conversation-status status-fadein panel-body"
@goto="setHighlight"
@toggleExpanded="toggleExpanded"
/>
<div class="conversation-body panel-body">
<div
v-if="isTreeView"
class="thread-body"
>
<div
v-if="shouldShowAllConversationButton"
class="conversation-dive-to-top-level-box"
>
<i18n-t
keypath="status.show_all_conversation_with_icon"
tag="button"
class="button-unstyled -link"
scope="global"
@click.prevent="diveToTopLevel"
>
<template #icon>
<FAIcon
icon="angle-double-left"
/>
</template>
<template #text>
<span>
{{ $tc('status.show_all_conversation', otherTopLevelCount, { numStatus: otherTopLevelCount }) }}
</span>
</template>
</i18n-t>
</div>
<div
v-if="shouldShowAncestors"
class="thread-ancestors"
>
<div
v-for="status in ancestorsOf(diveRoot)"
:key="status.id"
class="thread-ancestor"
:class="{'thread-ancestor-has-other-replies': getReplies(status.id).length > 1, '-faded': shouldFadeAncestors}"
>
<status
ref="statusComponent"
:inline-expanded="collapsable && isExpanded"
:statusoid="status"
:expandable="!isExpanded"
:show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
:focused="focused(status.id)"
:in-conversation="isExpanded"
:highlight="getHighlight()"
:replies="getReplies(status.id)"
:in-profile="inProfile"
:profile-user-id="profileUserId"
class="conversation-status status-fadein panel-body"
:simple-tree="treeViewIsSimple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively"
:total-reply-count="totalReplyCount"
:total-reply-depth="totalReplyDepth"
:show-other-replies-as-button="showOtherRepliesButtonInsideStatus"
:dive="() => diveIntoStatus(status.id)"
:controlled-showing-tall="statusContentProperties[status.id].showingTall"
:controlled-expanding-subject="statusContentProperties[status.id].expandingSubject"
:controlled-showing-long-subject="statusContentProperties[status.id].showingLongSubject"
:controlled-replying="statusContentProperties[status.id].replying"
:controlled-media-playing="statusContentProperties[status.id].mediaPlaying"
:controlled-toggle-showing-tall="() => toggleStatusContentProperty(status.id, 'showingTall')"
:controlled-toggle-expanding-subject="() => toggleStatusContentProperty(status.id, 'expandingSubject')"
:controlled-toggle-showing-long-subject="() => toggleStatusContentProperty(status.id, 'showingLongSubject')"
:controlled-toggle-replying="() => toggleStatusContentProperty(status.id, 'replying')"
:controlled-set-media-playing="(newVal) => toggleStatusContentProperty(status.id, 'mediaPlaying', newVal)"
@goto="setHighlight"
@toggleExpanded="toggleExpanded"
/>
<div
v-if="showOtherRepliesButtonBelowStatus && getReplies(status.id).length > 1"
class="thread-ancestor-dive-box"
>
<div
class="thread-ancestor-dive-box-inner"
>
<i18n-t
tag="button"
scope="global"
keypath="status.ancestor_follow_with_icon"
class="button-unstyled -link thread-tree-show-replies-button"
@click.prevent="diveIntoStatus(status.id)"
>
<template #icon>
<FAIcon
icon="angle-double-right"
/>
</template>
<template #text>
<span>
{{ $tc('status.ancestor_follow', getReplies(status.id).length - 1, { numReplies: getReplies(status.id).length - 1 }) }}
</span>
</template>
</i18n-t>
</div>
</div>
</div>
</div>
<thread-tree
v-for="status in showingTopLevel"
:key="status.id"
ref="statusComponent"
:depth="0"
:status="status"
:in-profile="inProfile"
:conversation="conversation"
:collapsable="collapsable"
:is-expanded="isExpanded"
:pinned-status-ids-object="pinnedStatusIdsObject"
:profile-user-id="profileUserId"
:focused="focused"
:get-replies="getReplies"
:highlight="maybeHighlight"
:set-highlight="setHighlight"
:toggle-expanded="toggleExpanded"
:simple="treeViewIsSimple"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively"
:total-reply-count="totalReplyCount"
:total-reply-depth="totalReplyDepth"
:status-content-properties="statusContentProperties"
:set-status-content-property="setStatusContentProperty"
:toggle-status-content-property="toggleStatusContentProperty"
:dive="canDive ? diveIntoStatus : undefined"
/>
</div>
<div
v-if="isLinearView"
class="thread-body"
>
<status
v-for="status in conversation"
:key="status.id"
ref="statusComponent"
:inline-expanded="collapsable && isExpanded"
:statusoid="status"
:expandable="!isExpanded"
:show-pinned="pinnedStatusIdsObject && pinnedStatusIdsObject[status.id]"
:focused="focused(status.id)"
:in-conversation="isExpanded"
:highlight="getHighlight()"
:replies="getReplies(status.id)"
:in-profile="inProfile"
:profile-user-id="profileUserId"
class="conversation-status status-fadein panel-body"
:toggle-thread-display="toggleThreadDisplay"
:thread-display-status="threadDisplayStatus"
:show-thread-recursively="showThreadRecursively"
:total-reply-count="totalReplyCount"
:total-reply-depth="totalReplyDepth"
:status-content-properties="statusContentProperties"
:set-status-content-property="setStatusContentProperty"
:toggle-status-content-property="toggleStatusContentProperty"
@goto="setHighlight"
@toggleExpanded="toggleExpanded"
/>
</div>
</div>
</div>
<div
v-else
@ -49,6 +201,48 @@
@import '../../_variables.scss';
.Conversation {
z-index: 1;
.conversation-dive-to-top-level-box {
padding: var(--status-margin, $status-margin);
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: var(--border, $fallback--border);
border-radius: 0;
/* Make the button stretch along the whole row */
display: flex;
align-items: stretch;
flex-direction: column;
}
.thread-ancestors {
margin-left: var(--status-margin, $status-margin);
border-left: 2px solid var(--border, $fallback--border);
}
.thread-ancestor.-faded .StatusContent {
--link: var(--faintLink);
--text: var(--faint);
color: var(--text);
}
.thread-ancestor-dive-box {
padding-left: var(--status-margin, $status-margin);
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: var(--border, $fallback--border);
border-radius: 0;
/* Make the button stretch along the whole row */
&, &-inner {
display: flex;
align-items: stretch;
flex-direction: column;
}
}
.thread-ancestor-dive-box-inner {
padding: var(--status-margin, $status-margin);
}
.conversation-status {
border-bottom-width: 1px;
border-bottom-style: solid;
@ -56,12 +250,33 @@
border-radius: 0;
}
&.-expanded {
.conversation-status:last-child {
border-bottom: none;
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
}
.thread-ancestor-has-other-replies .conversation-status,
.thread-ancestor:last-child .conversation-status,
.thread-ancestor:last-child .thread-ancestor-dive-box,
&:last-child .conversation-status,
&.-expanded .thread-tree .conversation-status {
border-bottom: none;
}
.thread-ancestors + .thread-tree > .conversation-status {
border-top-width: 1px;
border-top-style: solid;
border-top-color: var(--border, $fallback--border);
}
/* expanded conversation in timeline */
&.status-fadein.-expanded .thread-body {
border-left-width: 4px;
border-left-style: solid;
border-left-color: $fallback--cRed;
border-left-color: var(--cRed, $fallback--cRed);
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
border-bottom: 1px solid var(--border, $fallback--border);
}
&.-expanded.status-fadein {
margin: calc(var(--status-margin, $status-margin) / 2);
}
}
</style>

View file

@ -1,9 +1,7 @@
@import '../../_variables.scss';
.DesktopNav {
height: 50px;
width: 100%;
position: fixed;
a {
color: var(--topBarLink, $fallback--link);
@ -11,7 +9,7 @@
.inner-nav {
display: grid;
grid-template-rows: 50px;
grid-template-rows: var(--navbar-height);
grid-template-columns: 2fr auto 2fr;
grid-template-areas: "sitename logo actions";
box-sizing: border-box;
@ -20,7 +18,7 @@
max-width: 980px;
}
&.-logoLeft {
&.-logoLeft .inner-nav {
grid-template-columns: auto 2fr 2fr;
grid-template-areas: "logo sitename actions";
}
@ -77,16 +75,21 @@
img {
display: inline-block;
height: 50px;
height: var(--navbar-height);
}
}
.nav-icon {
margin-left: 0.2em;
margin-left: 1em;
width: 2em;
height: 100%;
font-size: 130%;
text-align: center;
&-logout {
margin-left: 2em;
}
.svg-inline--fa {
color: $fallback--link;
color: var(--topBarLink, $fallback--link);
@ -103,8 +106,8 @@
.item {
flex: 1;
line-height: 50px;
height: 50px;
line-height: var(--navbar-height);
height: var(--navbar-height);
overflow: hidden;
display: flex;
flex-wrap: wrap;

View file

@ -34,7 +34,7 @@
<search-bar
v-if="currentUser || !privateMode"
@toggled="onSearchBarToggled"
@click.stop.native
@click.stop
/>
<button
class="button-unstyled nav-icon"
@ -52,6 +52,7 @@
href="/pleroma/admin/#/login-pleroma"
class="nav-icon"
target="_blank"
@click.stop
>
<FAIcon
fixed-width
@ -62,7 +63,7 @@
</a>
<button
v-if="currentUser"
class="button-unstyled nav-icon"
class="button-unstyled nav-icon nav-icon-logout"
@click.prevent="logout"
>
<FAIcon

View file

@ -58,16 +58,7 @@
background-color: var(--bg, $fallback--bg);
.dialog-modal-heading {
padding: .5em .5em;
margin-right: auto;
margin-bottom: 0;
white-space: nowrap;
color: var(--panelText);
background-color: $fallback--fg;
background-color: var(--panel, $fallback--fg);
.title {
margin-bottom: 0;
text-align: center;
}
}

View file

@ -31,6 +31,7 @@ library.add(
*/
const EmojiInput = {
emits: ['update:modelValue', 'shown'],
props: {
suggest: {
/**
@ -57,8 +58,7 @@ const EmojiInput = {
required: true,
type: Function
},
// TODO VUE3: change to modelValue, change 'input' event to 'input'
value: {
modelValue: {
/**
* Used for v-model
*/
@ -137,8 +137,8 @@ const EmojiInput = {
return (this.wordAtCaret || {}).word || ''
},
wordAtCaret () {
if (this.value && this.caret) {
const word = Completion.wordAtPosition(this.value, this.caret - 1) || {}
if (this.modelValue && this.caret) {
const word = Completion.wordAtPosition(this.modelValue, this.caret - 1) || {}
return word
}
}
@ -189,8 +189,11 @@ const EmojiInput = {
img: imageUrl || ''
}))
},
suggestions (newValue) {
this.$nextTick(this.resize)
suggestions: {
handler (newValue) {
this.$nextTick(this.resize)
},
deep: true
}
},
methods: {
@ -225,13 +228,13 @@ const EmojiInput = {
}
},
replace (replacement) {
const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement)
this.$emit('input', newValue)
const newValue = Completion.replaceWord(this.modelValue, this.wordAtCaret, replacement)
this.$emit('update:modelValue', newValue)
this.caret = 0
},
insert ({ insertion, keepOpen, surroundingSpace = true }) {
const before = this.value.substring(0, this.caret) || ''
const after = this.value.substring(this.caret) || ''
const before = this.modelValue.substring(0, this.caret) || ''
const after = this.modelValue.substring(this.caret) || ''
/* Using a bit more smart approach to padding emojis with spaces:
* - put a space before cursor if there isn't one already, unless we
@ -259,7 +262,7 @@ const EmojiInput = {
after
].join('')
this.keepOpen = keepOpen
this.$emit('input', newValue)
this.$emit('update:modelValue', newValue)
const position = this.caret + (insertion + spaceAfter + spaceBefore).length
if (!keepOpen) {
this.input.focus()
@ -278,8 +281,8 @@ const EmojiInput = {
if (len > 0 || suggestion) {
const chosenSuggestion = suggestion || this.suggestions[this.highlighted]
const replacement = chosenSuggestion.replacement
const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement)
this.$emit('input', newValue)
const newValue = Completion.replaceWord(this.modelValue, this.wordAtCaret, replacement)
this.$emit('update:modelValue', newValue)
this.highlighted = 0
const position = this.wordAtCaret.start + replacement.length
@ -455,7 +458,7 @@ const EmojiInput = {
this.showPicker = false
this.setCaret(e)
this.resize()
this.$emit('input', e.target.value)
this.$emit('update:modelValue', e.target.value)
},
onClickInput (e) {
this.showPicker = false

View file

@ -78,7 +78,7 @@
top: 0;
right: 0;
margin: .2em .25em;
font-size: 16px;
font-size: 1.3em;
cursor: pointer;
line-height: 24px;

View file

@ -1,3 +1,4 @@
import { defineAsyncComponent } from 'vue'
import Checkbox from '../checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@ -57,7 +58,7 @@ const EmojiPicker = {
}
},
components: {
StickerPicker: () => import('../sticker_picker/sticker_picker.vue'),
StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')),
Checkbox
},
methods: {
@ -79,7 +80,7 @@ const EmojiPicker = {
},
highlight (key) {
const ref = this.$refs['group-' + key]
const top = ref[0].offsetTop
const top = ref.offsetTop
this.setShowStickers(false)
this.activeGroup = key
this.$nextTick(() => {
@ -96,7 +97,7 @@ const EmojiPicker = {
}
},
triggerLoadMore (target) {
const ref = this.$refs['group-end-custom'][0]
const ref = this.$refs['group-end-custom']
if (!ref) return
const bottom = ref.offsetTop + ref.offsetHeight
@ -119,7 +120,7 @@ const EmojiPicker = {
this.$nextTick(() => {
this.emojisView.forEach(group => {
const ref = this.$refs['group-' + group.id]
if (ref[0].offsetTop <= top) {
if (ref.offsetTop <= top) {
this.activeGroup = group.id
}
})

View file

@ -7,7 +7,7 @@
right: 0;
left: 0;
margin: 0 !important;
z-index: 1;
z-index: 100;
background-color: $fallback--bg;
background-color: var(--popover, $fallback--bg);
color: $fallback--link;
@ -73,12 +73,13 @@
&-item {
padding: 0 7px;
cursor: pointer;
font-size: 24px;
font-size: 1.85em;
&.disabled {
opacity: 0.5;
pointer-events: none;
}
&.active {
border-bottom: 4px solid;
@ -151,9 +152,10 @@
justify-content: left;
&-title {
font-size: 12px;
font-size: 0.85em;
width: 100%;
margin: 0;
&.disabled {
display: none;
}

View file

@ -11,8 +11,23 @@
@click="emojiOnClick(reaction.name, $event)"
@mouseenter="fetchEmojiReactionsByIfMissing()"
>
<span class="reaction-emoji">{{ reaction.name }}</span>
<span>{{ reaction.count }}</span>
<span
v-if="reaction.url !== null"
>
<img
:src="reaction.url"
:title="reaction.name"
class="reaction-emoji"
width="2.55em"
>
{{ reaction.count }}
</span>
<span v-else>
<span class="reaction-emoji unicode-emoji">
{{ reaction.name }}
</span>
<span>{{ reaction.count }}</span>
</span>
</button>
</UserListPopover>
<a
@ -36,6 +51,10 @@
flex-wrap: wrap;
}
.unicode-emoji {
font-size: 210%;
}
.emoji-reaction {
padding: 0 0.5em;
margin-right: 0.5em;
@ -45,7 +64,7 @@
justify-content: center;
box-sizing: border-box;
.reaction-emoji {
width: 1.25em;
width: 2.55em !important;
margin-right: 0.25em;
}
&:focus {

View file

@ -15,18 +15,8 @@ const Exporter = {
type: String,
default: 'export.csv'
},
exportButtonLabel: {
type: String,
default () {
return this.$t('exporter.export')
}
},
processingMessage: {
type: String,
default () {
return this.$t('exporter.processing')
}
}
exportButtonLabel: { type: String },
processingMessage: { type: String }
},
data () {
return {

View file

@ -7,14 +7,14 @@
spin
/>
<span>{{ processingMessage }}</span>
<span>{{ processingMessage || $t('exporter.processing') }}</span>
</div>
<button
v-else
class="btn button-default"
@click="process"
>
{{ exportButtonLabel }}
{{ exportButtonLabel || $t('exporter.export') }}
</button>
</div>
</template>

View file

@ -39,12 +39,13 @@ const Flash = {
this.player = 'error'
})
this.ruffleInstance = player
this.$emit('playerOpened')
})
},
closePlayer () {
console.log(this.ruffleInstance)
this.ruffleInstance.remove()
this.ruffleInstance && this.ruffleInstance.remove()
this.player = false
this.$emit('playerClosed')
}
}
}

View file

@ -36,13 +36,6 @@
</p>
</span>
</button>
<button
v-if="player"
class="button-unstyled hider"
@click="closePlayer"
>
<FAIcon icon="stop" />
</button>
</div>
</template>
@ -51,8 +44,9 @@
<style lang="scss">
@import '../../_variables.scss';
.Flash {
display: inline-block;
width: 100%;
height: 260px;
height: 100%;
position: relative;
.player {
@ -60,6 +54,16 @@
width: 100%;
}
.placeholder {
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg);
color: var(--link);
}
.hider {
top: 0;
}
@ -76,13 +80,5 @@
display: none;
visibility: 'hidden';
}
.placeholder {
height: 100%;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

View file

@ -1,6 +1,6 @@
import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
export default {
props: ['relationship', 'labelFollowing', 'buttonClass'],
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
data () {
return {
inProgress: false
@ -14,7 +14,7 @@ export default {
if (this.inProgress || this.relationship.following) {
return this.$t('user_card.follow_unfollow')
} else if (this.relationship.requested) {
return this.$t('user_card.follow_again')
return this.$t('user_card.follow_cancel')
} else {
return this.$t('user_card.follow')
}
@ -29,11 +29,14 @@ export default {
} else {
return this.$t('user_card.follow')
}
},
disabled () {
return this.inProgress || this.user.deactivated
}
},
methods: {
onClick () {
this.relationship.following ? this.unfollow() : this.follow()
this.relationship.following || this.relationship.requested ? this.unfollow() : this.follow()
},
follow () {
this.inProgress = true

View file

@ -2,7 +2,7 @@
<button
class="btn button-default follow-button"
:class="{ toggled: isPressed }"
:disabled="inProgress"
:disabled="disabled"
:title="title"
@click="onClick"
>

View file

@ -20,6 +20,7 @@
:relationship="relationship"
:label-following="$t('user_card.follow_unfollow')"
class="follow-card-follow-button"
:user="user"
/>
</template>
</div>

View file

@ -1,4 +1,4 @@
import { set } from 'vue'
import { set } from 'lodash'
import Select from '../select/select.vue'
export default {
@ -6,11 +6,12 @@ export default {
Select
},
props: [
'name', 'label', 'value', 'fallback', 'options', 'no-inherit'
'name', 'label', 'modelValue', 'fallback', 'options', 'no-inherit'
],
emits: ['update:modelValue'],
data () {
return {
lValue: this.value,
lValue: this.modelValue,
availableOptions: [
this.noInherit ? '' : 'inherit',
'custom',
@ -22,7 +23,7 @@ export default {
}
},
beforeUpdate () {
this.lValue = this.value
this.lValue = this.modelValue
},
computed: {
present () {
@ -37,7 +38,7 @@ export default {
},
set (v) {
set(this.lValue, 'family', v)
this.$emit('input', this.lValue)
this.$emit('update:modelValue', this.lValue)
}
},
isCustom () {

View file

@ -15,13 +15,14 @@
class="opt exlcude-disabled"
type="checkbox"
:checked="present"
@input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
@change="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)"
>
<label
v-if="typeof fallback !== 'undefined'"
class="opt-l"
:for="name + '-o'"
/>
{{ ' ' }}
<Select
:id="name + '-font-switcher'"
v-model="preset"

View file

@ -1,15 +1,26 @@
import Attachment from '../attachment/attachment.vue'
import { chunk, last, dropRight, sumBy } from 'lodash'
import { sumBy, set } from 'lodash'
const Gallery = {
props: [
'attachments',
'limitRows',
'descriptions',
'limit',
'nsfw',
'setMedia'
'setMedia',
'size',
'editable',
'removeAttachment',
'shiftUpAttachment',
'shiftDnAttachment',
'editAttachment',
'grid'
],
data () {
return {
sizes: {}
sizes: {},
hidingLong: true
}
},
components: { Attachment },
@ -18,26 +29,70 @@ const Gallery = {
if (!this.attachments) {
return []
}
const rows = chunk(this.attachments, 3)
if (last(rows).length === 1 && rows.length > 1) {
// if 1 attachment on last row -> add it to the previous row instead
const lastAttachment = last(rows)[0]
const allButLastRow = dropRight(rows)
last(allButLastRow).push(lastAttachment)
return allButLastRow
const attachments = this.limit > 0
? this.attachments.slice(0, this.limit)
: this.attachments
if (this.size === 'hide') {
return attachments.map(item => ({ minimal: true, items: [item] }))
}
const rows = this.grid
? [{ grid: true, items: attachments }]
: attachments.reduce((acc, attachment, i) => {
if (attachment.mimetype.includes('audio')) {
return [...acc, { audio: true, items: [attachment] }, { items: [] }]
}
if (!(
attachment.mimetype.includes('image') ||
attachment.mimetype.includes('video') ||
attachment.mimetype.includes('flash')
)) {
return [...acc, { minimal: true, items: [attachment] }, { items: [] }]
}
const maxPerRow = 3
const attachmentsRemaining = this.attachments.length - i + 1
const currentRow = acc[acc.length - 1].items
currentRow.push(attachment)
if (currentRow.length >= maxPerRow && attachmentsRemaining > maxPerRow) {
return [...acc, { items: [] }]
} else {
return acc
}
}, [{ items: [] }]).filter(_ => _.items.length > 0)
return rows
},
useContainFit () {
return this.$store.getters.mergedConfig.useContainFit
attachmentsDimensionalScore () {
return this.rows.reduce((acc, row) => {
let size = 0
if (row.minimal) {
size += 1 / 8
} else if (row.audio) {
size += 1 / 4
} else {
size += 1 / (row.items.length + 0.6)
}
return acc + size
}, 0)
},
tooManyAttachments () {
if (this.editable || this.size === 'small') {
return false
} else if (this.size === 'hide') {
return this.attachments.length > 8
} else {
return this.attachmentsDimensionalScore > 1
}
}
},
methods: {
onNaturalSizeLoad (id, size) {
this.$set(this.sizes, id, size)
onNaturalSizeLoad ({ id, width, height }) {
set(this.sizes, id, { width, height })
},
rowStyle (itemsPerRow) {
return { 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` }
rowStyle (row) {
if (row.audio) {
return { 'padding-bottom': '25%' } // fixed reduced height for audio
} else if (!row.minimal && !row.grid) {
return { 'padding-bottom': `${(100 / (row.items.length + 0.6))}%` }
}
},
itemStyle (id, row) {
const total = sumBy(row, item => this.getAspectRatio(item.id))
@ -46,6 +101,16 @@ const Gallery = {
getAspectRatio (id) {
const size = this.sizes[id]
return size ? size.width / size.height : 1
},
toggleHidingLong (event) {
this.hidingLong = event
},
openGallery () {
this.$store.dispatch('setMedia', this.attachments)
this.$store.dispatch('setCurrentMedia', this.attachments[0])
},
onMedia () {
this.$store.dispatch('setMedia', this.attachments)
}
}
}

View file

@ -1,26 +1,83 @@
<template>
<div
ref="galleryContainer"
style="width: 100%;"
class="Gallery"
:class="{ '-long': tooManyAttachments && hidingLong }"
>
<div class="gallery-rows">
<div
v-for="(row, rowIndex) in rows"
:key="rowIndex"
class="gallery-row"
:style="rowStyle(row)"
:class="{ '-audio': row.audio, '-minimal': row.minimal, '-grid': grid }"
>
<div
class="gallery-row-inner"
:class="{ '-grid': grid }"
>
<Attachment
v-for="(attachment, attachmentIndex) in row.items"
:key="attachment.id"
class="gallery-item"
:nsfw="nsfw"
:attachment="attachment"
:size="size"
:editable="editable"
:remove="removeAttachment"
:shift-up="!(attachmentIndex === 0 && rowIndex === 0) && shiftUpAttachment"
:shift-dn="!(attachmentIndex === row.items.length - 1 && rowIndex === rows.length - 1) && shiftDnAttachment"
:edit="editAttachment"
:description="descriptions && descriptions[attachment.id]"
:hide-description="size === 'small' || tooManyAttachments && hidingLong"
:style="itemStyle(attachment.id, row.items)"
@setMedia="onMedia"
@naturalSizeLoad="onNaturalSizeLoad"
/>
</div>
</div>
</div>
<div
v-for="(row, index) in rows"
:key="index"
class="gallery-row"
:style="rowStyle(row.length)"
:class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
v-if="tooManyAttachments"
class="many-attachments"
>
<div class="gallery-row-inner">
<attachment
v-for="attachment in row"
:key="attachment.id"
:set-media="setMedia"
:nsfw="nsfw"
:attachment="attachment"
:allow-play="false"
:natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
:style="itemStyle(attachment.id, row)"
/>
<div class="many-attachments-text">
{{ $t("status.many_attachments", { number: attachments.length }) }}
</div>
<div class="many-attachments-buttons">
<span
v-if="!hidingLong"
class="many-attachments-button"
>
<button
class="button-unstyled -link"
@click="toggleHidingLong(true)"
>
{{ $t("status.collapse_attachments") }}
</button>
</span>
<span
v-if="hidingLong"
class="many-attachments-button"
>
<button
class="button-unstyled -link"
@click="toggleHidingLong(false)"
>
{{ $t("status.show_all_attachments") }}
</button>
</span>
<span
v-if="hidingLong"
class="many-attachments-button"
>
<button
class="button-unstyled -link"
@click="openGallery"
>
{{ $t("status.open_gallery") }}
</button>
</span>
</div>
</div>
</div>
@ -31,12 +88,66 @@
<style lang="scss">
@import '../../_variables.scss';
.gallery-row {
position: relative;
height: 0;
width: 100%;
flex-grow: 1;
margin-top: 0.5em;
.Gallery {
.gallery-rows {
display: flex;
flex-direction: column;
}
.gallery-row {
position: relative;
height: 0;
width: 100%;
flex-grow: 1;
&:not(:first-child) {
margin-top: 0.5em;
}
}
&.-long {
.gallery-rows {
max-height: 25em;
overflow: hidden;
mask:
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
linear-gradient(to top, white, white);
/* Autoprefixed seem to ignore this one, and also syntax is different */
-webkit-mask-composite: xor;
mask-composite: exclude;
}
}
.many-attachments-text {
text-align: center;
line-height: 2;
}
.many-attachments-buttons {
display: flex;
}
.many-attachments-button {
display: flex;
flex: 1;
justify-content: center;
line-height: 2;
button {
padding: 0 2em;
}
}
.gallery-row {
&.-grid,
&.-minimal {
height: auto;
.gallery-row-inner {
position: relative;
}
}
}
.gallery-row-inner {
position: absolute;
@ -48,9 +159,23 @@
flex-direction: row;
flex-wrap: nowrap;
align-content: stretch;
&.-grid {
width: 100%;
height: auto;
position: relative;
display: grid;
grid-column-gap: 0.5em;
grid-row-gap: 0.5em;
grid-template-columns: repeat(auto-fill, minmax(15em, 1fr));
.gallery-item {
margin: 0;
}
}
}
.gallery-row-inner .attachment {
.gallery-item {
margin: 0 0.5em 0 0;
flex-grow: 1;
height: 100%;
@ -61,32 +186,5 @@
margin: 0;
}
}
.image-attachment {
width: 100%;
height: 100%;
}
.video-container {
height: 100%;
}
&.contain-fit {
img,
video,
canvas {
object-fit: contain;
height: 100%;
}
}
&.cover-fit {
img,
video,
canvas {
object-fit: cover;
}
}
}
</style>

View file

@ -44,20 +44,18 @@
max-width: calc(100% - 3em);
display: flex;
padding-left: 1.5em;
line-height: 2em;
line-height: 2;
margin-bottom: 0.5em;
.notice-message {
flex: 1 1 100%;
}
i {
flex: 0 0;
width: 1.5em;
cursor: pointer;
}
}
.global-error {
background-color: var(--alertPopupError, $fallback--cRed);
color: var(--alertPopupErrorText, $fallback--text);
.svg-inline--fa {
color: var(--alertPopupErrorText, $fallback--text);
}
@ -66,6 +64,7 @@
.global-warning {
background-color: var(--alertPopupWarning, $fallback--cOrange);
color: var(--alertPopupWarningText, $fallback--text);
.svg-inline--fa {
color: var(--alertPopupWarningText, $fallback--text);
}

View file

@ -0,0 +1,36 @@
import { extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
const HashtagLink = {
name: 'HashtagLink',
props: {
url: {
required: true,
type: String
},
content: {
required: true,
type: String
},
tag: {
required: false,
type: String,
default: ''
}
},
methods: {
onClick () {
const tag = this.tag || extractTagFromUrl(this.url)
if (tag) {
const link = this.generateTagLink(tag)
this.$router.push(link)
} else {
window.open(this.url, '_blank')
}
},
generateTagLink (tag) {
return `/tag/${tag}`
}
}
}
export default HashtagLink

View file

@ -0,0 +1,6 @@
.HashtagLink {
position: relative;
white-space: normal;
display: inline-block;
color: var(--link);
}

View file

@ -0,0 +1,19 @@
<template>
<span
class="HashtagLink"
>
<!-- eslint-disable vue/no-v-html -->
<a
:href="url"
class="original"
target="_blank"
@click.prevent="onClick"
v-html="content"
/>
<!-- eslint-enable vue/no-v-html -->
</span>
</template>
<script src="./hashtag_link.js"/>
<style lang="scss" src="./hashtag_link.scss"/>

View file

@ -117,7 +117,7 @@ const ImageCropper = {
const fileInput = this.$refs.input
fileInput.addEventListener('change', this.readFile)
},
beforeDestroy: function () {
beforeUnmount: function () {
// remove the event listeners
const trigger = this.getTriggerDOM()
if (trigger) {

View file

@ -15,24 +15,9 @@ const Importer = {
type: Function,
required: true
},
submitButtonLabel: {
type: String,
default () {
return this.$t('importer.submit')
}
},
successMessage: {
type: String,
default () {
return this.$t('importer.success')
}
},
errorMessage: {
type: String,
default () {
return this.$t('importer.error')
}
}
submitButtonLabel: { type: String },
successMessage: { type: String },
errorMessage: { type: String }
},
data () {
return {

View file

@ -18,21 +18,31 @@
class="btn button-default"
@click="submit"
>
{{ submitButtonLabel }}
{{ submitButtonLabel || $t('importer.submit') }}
</button>
<div v-if="success">
<FAIcon
icon="times"
<button
class="button-unstyled"
@click="dismiss"
/>
<p>{{ successMessage }}</p>
>
<FAIcon
icon="times"
/>
</button>
{{ ' ' }}
<span>{{ successMessage || $t('importer.success') }}</span>
</div>
<div v-else-if="error">
<FAIcon
icon="times"
<button
class="button-unstyled"
@click="dismiss"
/>
<p>{{ errorMessage }}</p>
>
<FAIcon
icon="times"
/>
</button>
{{ ' ' }}
<span>{{ errorMessage || $t('importer.error') }}</span>
</div>
</div>
</template>

View file

@ -1,4 +1,5 @@
import Notifications from '../notifications/notifications.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
const tabModeDict = {
mentions: ['mention'],
@ -20,7 +21,8 @@ const Interactions = {
}
},
components: {
Notifications
Notifications,
TabSwitcher
}
}

View file

@ -1,11 +1,12 @@
<template>
<div>
<label for="interface-language-switcher">
{{ $t('settings.interfaceLanguage') }}
{{ promptText }}
</label>
{{ ' ' }}
<Select
id="interface-language-switcher"
v-model="language"
v-model="controlledLanguage"
>
<option
v-for="lang in languages"
@ -19,39 +20,43 @@
</template>
<script>
import languagesObject from '../../i18n/messages'
import localeService from '../../services/locale/locale.service.js'
import ISO6391 from 'iso-639-1'
import _ from 'lodash'
import Select from '../select/select.vue'
export default {
components: {
Select
},
props: {
promptText: {
type: String,
required: true
},
language: {
type: String,
required: true
},
setLanguage: {
type: Function,
required: true
}
},
computed: {
languages () {
return _.map(languagesObject.languages, (code) => ({ code: code, name: this.getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name))
return localeService.languages
},
language: {
get: function () { return this.$store.getters.mergedConfig.interfaceLanguage },
controlledLanguage: {
get: function () { return this.language },
set: function (val) {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
this.setLanguage(val)
}
}
},
methods: {
getLanguageName (code) {
const specialLanguageNames = {
'ja_easy': 'やさしいにほんご',
'zh': '简体中文',
'zh_Hant': '繁體中文'
}
const languageName = specialLanguageNames[code] || ISO6391.getNativeName(code)
const browserLocale = localeService.internalToBrowserLocale(code)
return languageName.charAt(0).toLocaleUpperCase(browserLocale) + languageName.slice(1)
return localeService.getLanguageName(code)
}
}
}

View file

@ -63,7 +63,7 @@
}
.card-host {
font-size: 12px;
font-size: 0.85em;
}
.card-description {

View file

@ -0,0 +1,16 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEllipsisH
} from '@fortawesome/free-solid-svg-icons'
library.add(
faEllipsisH
)
const ListCard = {
props: [
'list'
]
}
export default ListCard

View file

@ -0,0 +1,51 @@
<template>
<div class="list-card">
<router-link
:to="{ name: 'list-timeline', params: { id: list.id } }"
class="list-name"
>
{{ list.title }}
</router-link>
<router-link
:to="{ name: 'list-edit', params: { id: list.id } }"
class="button-list-edit"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="ellipsis-h"
/>
</router-link>
</div>
</template>
<script src="./list_card.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.list-card {
display: flex;
}
.list-name,
.button-list-edit {
margin: 0;
padding: 1em;
color: $fallback--link;
color: var(--link, $fallback--link);
&:hover {
background-color: $fallback--lightBg;
background-color: var(--selectedMenu, $fallback--lightBg);
color: $fallback--link;
color: var(--selectedMenuText, $fallback--link);
--faint: var(--selectedMenuFaintText, $fallback--faint);
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
--lightText: var(--selectedMenuLightText, $fallback--lightText);
}
}
.list-name {
flex-grow: 1;
}
</style>

View file

@ -0,0 +1,91 @@
import { mapState, mapGetters } from 'vuex'
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import ListUserSearch from '../list_user_search/list_user_search.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSearch,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSearch,
faChevronLeft
)
const ListNew = {
components: {
BasicUserCard,
UserAvatar,
ListUserSearch
},
data () {
return {
title: '',
userIds: [],
selectedUserIds: []
}
},
created () {
this.$store.dispatch('fetchList', { id: this.id })
.then(() => { this.title = this.findListTitle(this.id) })
this.$store.dispatch('fetchListAccounts', { id: this.id })
.then(() => {
this.selectedUserIds = this.findListAccounts(this.id)
this.selectedUserIds.forEach(userId => {
this.$store.dispatch('fetchUserIfMissing', userId)
})
})
},
computed: {
id () {
return this.$route.params.id
},
users () {
return this.userIds.map(userId => this.findUser(userId))
},
selectedUsers () {
return this.selectedUserIds.map(userId => this.findUser(userId)).filter(user => user)
},
...mapState({
currentUser: state => state.users.currentUser
}),
...mapGetters(['findUser', 'findListTitle', 'findListAccounts'])
},
methods: {
onInput () {
this.search(this.query)
},
selectUser (user) {
if (this.selectedUserIds.includes(user.id)) {
this.removeUser(user.id)
} else {
this.addUser(user)
}
},
isSelected (user) {
return this.selectedUserIds.includes(user.id)
},
addUser (user) {
this.selectedUserIds.push(user.id)
},
removeUser (userId) {
this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
},
onResults (results) {
this.userIds = results
},
updateList () {
this.$store.dispatch('setList', { id: this.id, title: this.title })
this.$store.dispatch('setListAccounts', { id: this.id, accountIds: this.selectedUserIds })
this.$router.push({ name: 'list-timeline', params: { id: this.id } })
},
deleteList () {
this.$store.dispatch('deleteList', { id: this.id })
this.$router.push({ name: 'lists' })
}
}
}
export default ListNew

View file

@ -0,0 +1,108 @@
<template>
<div class="panel-default panel list-edit">
<div
ref="header"
class="panel-heading"
>
<button
class="button-unstyled go-back-button"
@click="$router.back"
>
<FAIcon
size="lg"
icon="chevron-left"
/>
</button>
</div>
<div class="input-wrap">
<input
ref="title"
v-model="title"
:placeholder="$t('lists.title')"
>
</div>
<div class="member-list">
<div
v-for="user in selectedUsers"
:key="user.id"
class="member"
>
<BasicUserCard
:user="user"
:class="isSelected(user) ? 'selected' : ''"
@click.capture.prevent="selectUser(user)"
/>
</div>
</div>
<ListUserSearch @results="onResults" />
<div class="member-list">
<div
v-for="user in users"
:key="user.id"
class="member"
>
<BasicUserCard
:user="user"
:class="isSelected(user) ? 'selected' : ''"
@click.capture.prevent="selectUser(user)"
/>
</div>
</div>
<button
:disabled="title && title.length === 0"
class="btn button-default"
@click="updateList"
>
{{ $t('lists.save') }}
</button>
<button
class="btn button-default"
@click="deleteList"
>
{{ $t('lists.delete') }}
</button>
</div>
</template>
<script src="./list_edit.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.list-edit {
.input-wrap {
display: flex;
margin: 0.7em 0.5em 0.7em 0.5em;
input {
width: 100%;
}
}
.search-icon {
margin-right: 0.3em;
}
.member-list {
padding-bottom: 0.7rem;
}
.basic-user-card:hover,
.basic-user-card.selected {
cursor: pointer;
background-color: var(--selectedPost, $fallback--lightBg);
}
.go-back-button {
text-align: center;
line-height: 1;
height: 100%;
align-self: start;
width: var(--__panel-heading-height-inner);
}
.btn {
margin: 0.5em;
}
}
</style>

View file

@ -0,0 +1,79 @@
import { mapState, mapGetters } from 'vuex'
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
import ListUserSearch from '../list_user_search/list_user_search.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSearch,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSearch,
faChevronLeft
)
const ListNew = {
components: {
BasicUserCard,
UserAvatar,
ListUserSearch
},
data () {
return {
title: '',
userIds: [],
selectedUserIds: []
}
},
computed: {
users () {
return this.userIds.map(userId => this.findUser(userId))
},
selectedUsers () {
return this.selectedUserIds.map(userId => this.findUser(userId))
},
...mapState({
currentUser: state => state.users.currentUser
}),
...mapGetters(['findUser'])
},
methods: {
goBack () {
this.$emit('cancel')
},
onInput () {
this.search(this.query)
},
selectUser (user) {
if (this.selectedUserIds.includes(user.id)) {
this.removeUser(user.id)
} else {
this.addUser(user)
}
},
isSelected (user) {
return this.selectedUserIds.includes(user.id)
},
addUser (user) {
this.selectedUserIds.push(user.id)
},
removeUser (userId) {
this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
},
onResults (results) {
this.userIds = results
},
createList () {
// the API has two different endpoints for "creating a list with a name"
// and "updating the accounts on the list".
this.$store.dispatch('createList', { title: this.title })
.then((list) => {
this.$store.dispatch('setListAccounts', { id: list.id, accountIds: this.selectedUserIds })
this.$router.push({ name: 'list-timeline', params: { id: list.id } })
})
}
}
}
export default ListNew

View file

@ -0,0 +1,95 @@
<template>
<div class="panel-default panel list-new">
<div
ref="header"
class="panel-heading"
>
<button
class="button-unstyled go-back-button"
@click="goBack"
>
<FAIcon
size="lg"
icon="chevron-left"
/>
</button>
</div>
<div class="input-wrap">
<input
ref="title"
v-model="title"
:placeholder="$t('lists.title')"
>
</div>
<div class="member-list">
<div
v-for="user in selectedUsers"
:key="user.id"
class="member"
>
<BasicUserCard
:user="user"
:class="isSelected(user) ? 'selected' : ''"
@click.capture.prevent="selectUser(user)"
/>
</div>
</div>
<ListUserSearch
@results="onResults"
/>
<div
v-for="user in users"
:key="user.id"
class="member"
>
<BasicUserCard
:user="user"
:class="isSelected(user) ? 'selected' : ''"
@click.capture.prevent="selectUser(user)"
/>
</div>
<button
:disabled="title && title.length === 0"
class="btn button-default"
@click="createList"
>
{{ $t('lists.create') }}
</button>
</div>
</template>
<script src="./list_new.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.list-new {
.search-icon {
margin-right: 0.3em;
}
.member-list {
padding-bottom: 0.7rem;
}
.basic-user-card:hover,
.basic-user-card.selected {
cursor: pointer;
background-color: var(--selectedPost, $fallback--lightBg);
}
.go-back-button {
text-align: center;
line-height: 1;
height: 100%;
align-self: start;
width: var(--__panel-heading-height-inner);
}
.btn {
margin: 0.5em;
}
}
</style>

View file

@ -0,0 +1,25 @@
import Timeline from '../timeline/timeline.vue'
const ListTimeline = {
data () {
return {
listId: null
}
},
components: {
Timeline
},
computed: {
timeline () { return this.$store.state.statuses.timelines.list }
},
created () {
this.listId = this.$route.params.id
this.$store.dispatch('fetchList', { id: this.listId })
this.$store.dispatch('startFetchingTimeline', { timeline: 'list', listId: this.listId })
},
unmounted () {
this.$store.dispatch('stopFetchingTimeline', 'list')
this.$store.commit('clearTimeline', { timeline: 'list' })
}
}
export default ListTimeline

View file

@ -0,0 +1,10 @@
<template>
<Timeline
title="list.name"
:timeline="timeline"
:list-id="listId"
timeline-name="list"
/>
</template>
<script src="./list_timeline.js"></script>

View file

@ -0,0 +1,46 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSearch,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons'
import { debounce } from 'lodash'
import Checkbox from '../checkbox/checkbox.vue'
library.add(
faSearch,
faChevronLeft
)
const ListUserSearch = {
components: {
Checkbox
},
data () {
return {
loading: false,
query: '',
followingOnly: true
}
},
methods: {
onInput: debounce(function () {
this.search(this.query)
}, 2000),
search (query) {
if (!query) {
this.loading = false
return
}
this.loading = true
this.userIds = []
this.$store.dispatch('search', { q: query, resolve: true, type: 'accounts', following: this.followingOnly })
.then(data => {
this.loading = false
this.$emit('results', data.accounts.map(a => a.id))
})
}
}
}
export default ListUserSearch

View file

@ -0,0 +1,45 @@
<template>
<div>
<div class="input-wrap">
<div class="input-search">
<FAIcon
class="search-icon fa-scale-110 fa-old-padding"
icon="search"
/>
</div>
<input
ref="search"
v-model="query"
:placeholder="$t('lists.search')"
@input="onInput"
>
</div>
<div class="input-wrap">
<Checkbox
v-model="followingOnly"
@change="onInput"
>
{{ $t('lists.following_only') }}
</Checkbox>
</div>
</div>
</template>
<script src="./list_user_search.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.input-wrap {
display: flex;
margin: 0.7em 0.5em 0.7em 0.5em;
input {
width: 100%;
}
}
.search-icon {
margin-right: 0.3em;
}
</style>

View file

@ -0,0 +1,32 @@
import ListCard from '../list_card/list_card.vue'
import ListNew from '../list_new/list_new.vue'
const Lists = {
data () {
return {
isNew: false
}
},
components: {
ListCard,
ListNew
},
created () {
this.$store.dispatch('startFetchingLists')
},
computed: {
lists () {
return this.$store.state.lists.allLists
}
},
methods: {
cancelNewList () {
this.isNew = false
},
newList () {
this.isNew = true
}
}
}
export default Lists

View file

@ -0,0 +1,31 @@
<template>
<div v-if="isNew">
<ListNew @cancel="cancelNewList" />
</div>
<div
v-else
class="settings panel panel-default"
>
<div class="panel-heading">
<div class="title">
{{ $t('lists.lists') }}
</div>
<button
class="button-default"
@click="newList"
>
{{ $t("lists.new") }}
</button>
</div>
<div class="panel-body">
<ListCard
v-for="list in lists.slice().reverse()"
:key="list"
:list="list"
class="list-item"
/>
</div>
</div>
</template>
<script src="./lists.js"></script>

View file

@ -76,11 +76,15 @@
>
<div class="alert error">
{{ error }}
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
<button
class="button-unstyled"
@click="clearError"
/>
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
/>
</button>
</div>
</div>
</div>
@ -97,7 +101,7 @@
padding: 0.6em;
.btn {
min-height: 28px;
min-height: 2em;
width: 10em;
}

View file

@ -1,24 +1,46 @@
import StillImage from '../still-image/still-image.vue'
import VideoAttachment from '../video_attachment/video_attachment.vue'
import Modal from '../modal/modal.vue'
import fileTypeService from '../../services/file_type/file_type.service.js'
import PinchZoom from '../pinch_zoom/pinch_zoom.vue'
import SwipeClick from '../swipe_click/swipe_click.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import Flash from 'src/components/flash/flash.vue'
import fileTypeService from '../../services/file_type/file_type.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronLeft,
faChevronRight
faChevronRight,
faCircleNotch,
faTimes
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronLeft,
faChevronRight
faChevronRight,
faCircleNotch,
faTimes
)
const MediaModal = {
components: {
StillImage,
VideoAttachment,
Modal
PinchZoom,
SwipeClick,
Modal,
Flash
},
data () {
return {
loading: false,
swipeDirection: GestureService.DIRECTION_LEFT,
swipeThreshold: () => {
const considerableMoveRatio = 1 / 4
return window.innerWidth * considerableMoveRatio
},
pinchZoomMinScale: 1,
pinchZoomScaleResetLimit: 1.2
}
},
computed: {
showing () {
@ -27,6 +49,9 @@ const MediaModal = {
media () {
return this.$store.state.mediaViewer.media
},
description () {
return this.currentMedia.description
},
currentIndex () {
return this.$store.state.mediaViewer.currentIndex
},
@ -37,43 +62,62 @@ const MediaModal = {
return this.media.length > 1
},
type () {
return this.currentMedia ? fileTypeService.fileType(this.currentMedia.mimetype) : null
return this.currentMedia ? this.getType(this.currentMedia) : null
}
},
created () {
this.mediaSwipeGestureRight = GestureService.swipeGesture(
GestureService.DIRECTION_RIGHT,
this.goPrev,
50
)
this.mediaSwipeGestureLeft = GestureService.swipeGesture(
GestureService.DIRECTION_LEFT,
this.goNext,
50
)
},
methods: {
mediaTouchStart (e) {
GestureService.beginSwipe(e, this.mediaSwipeGestureRight)
GestureService.beginSwipe(e, this.mediaSwipeGestureLeft)
},
mediaTouchMove (e) {
GestureService.updateSwipe(e, this.mediaSwipeGestureRight)
GestureService.updateSwipe(e, this.mediaSwipeGestureLeft)
getType (media) {
return fileTypeService.fileType(media.mimetype)
},
hide () {
this.$store.dispatch('closeMediaViewer')
// HACK: Closing immediately via a touch will cause the click
// to be processed on the content below the overlay
const transitionTime = 100 // ms
setTimeout(() => {
this.$store.dispatch('closeMediaViewer')
}, transitionTime)
},
hideIfNotSwiped (event) {
// If we have swiped over SwipeClick, do not trigger hide
const comp = this.$refs.swipeClick
if (!comp) {
this.hide()
} else {
comp.$gesture.click(event)
}
},
goPrev () {
if (this.canNavigate) {
const prevIndex = this.currentIndex === 0 ? this.media.length - 1 : (this.currentIndex - 1)
this.$store.dispatch('setCurrent', this.media[prevIndex])
const newMedia = this.media[prevIndex]
if (this.getType(newMedia) === 'image') {
this.loading = true
}
this.$store.dispatch('setCurrentMedia', newMedia)
}
},
goNext () {
if (this.canNavigate) {
const nextIndex = this.currentIndex === this.media.length - 1 ? 0 : (this.currentIndex + 1)
this.$store.dispatch('setCurrent', this.media[nextIndex])
const newMedia = this.media[nextIndex]
if (this.getType(newMedia) === 'image') {
this.loading = true
}
this.$store.dispatch('setCurrentMedia', newMedia)
}
},
onImageLoaded () {
this.loading = false
},
handleSwipePreview (offsets) {
this.$refs.pinchZoom.setTransform({ scale: 1, x: offsets[0], y: 0 })
},
handleSwipeEnd (sign) {
this.$refs.pinchZoom.setTransform({ scale: 1, x: 0, y: 0 })
if (sign > 0) {
this.goNext()
} else if (sign < 0) {
this.goPrev()
}
},
handleKeyupEvent (e) {
@ -98,7 +142,7 @@ const MediaModal = {
document.addEventListener('keyup', this.handleKeyupEvent)
document.addEventListener('keydown', this.handleKeydownEvent)
},
destroyed () {
unmounted () {
window.removeEventListener('popstate', this.hide)
document.removeEventListener('keyup', this.handleKeyupEvent)
document.removeEventListener('keydown', this.handleKeydownEvent)

View file

@ -2,18 +2,38 @@
<Modal
v-if="showing"
class="media-modal-view"
@backdropClicked="hide"
@backdropClicked="hideIfNotSwiped"
>
<img
<SwipeClick
v-if="type === 'image'"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
@touchstart.stop="mediaTouchStart"
@touchmove.stop="mediaTouchMove"
@click="hide"
ref="swipeClick"
class="modal-image-container"
:direction="swipeDirection"
:threshold="swipeThreshold"
@preview-requested="handleSwipePreview"
@swipe-finished="handleSwipeEnd"
@swipeless-clicked="hide"
>
<PinchZoom
ref="pinchZoom"
class="modal-image-container-inner"
selector=".modal-image"
reach-min-scale-strategy="reset"
stop-propagate-handled="stop-propgate-handled"
:allow-pan-min-scale="pinchZoomMinScale"
:min-scale="pinchZoomMinScale"
:reset-to-min-scale-limit="pinchZoomScaleResetLimit"
>
<img
:class="{ loading }"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
@load="onImageLoaded"
>
</PinchZoom>
</SwipeClick>
<VideoAttachment
v-if="type === 'video'"
class="modal-image"
@ -28,38 +48,84 @@
:title="currentMedia.description"
controls
/>
<Flash
v-if="type === 'flash'"
class="modal-image"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
/>
<button
v-if="canNavigate"
:title="$t('media_modal.previous')"
class="modal-view-button-arrow modal-view-button-arrow--prev"
class="modal-view-button modal-view-button-arrow modal-view-button-arrow--prev"
@click.stop.prevent="goPrev"
>
<FAIcon
class="arrow-icon"
class="button-icon arrow-icon"
icon="chevron-left"
/>
</button>
<button
v-if="canNavigate"
:title="$t('media_modal.next')"
class="modal-view-button-arrow modal-view-button-arrow--next"
class="modal-view-button modal-view-button-arrow modal-view-button-arrow--next"
@click.stop.prevent="goNext"
>
<FAIcon
class="arrow-icon"
class="button-icon arrow-icon"
icon="chevron-right"
/>
</button>
<button
class="modal-view-button modal-view-button-hide"
:title="$t('media_modal.hide')"
@click.stop.prevent="hide"
>
<FAIcon
class="button-icon"
icon="times"
/>
</button>
<span
v-if="description"
class="description"
>
{{ description }}
</span>
<span
class="counter"
>
{{ $tc('media_modal.counter', currentIndex + 1, { current: currentIndex + 1, total: media.length }) }}
</span>
<span
v-if="loading"
class="loading-spinner"
>
<FAIcon
spin
icon="circle-notch"
size="5x"
/>
</span>
</Modal>
</template>
<script src="./media_modal.js"></script>
<style lang="scss">
.modal-view.media-modal-view {
z-index: 1001;
$modal-view-button-icon-height: 3em;
$modal-view-button-icon-half-height: calc(#{$modal-view-button-icon-height} / 2);
$modal-view-button-icon-width: 3em;
$modal-view-button-icon-margin: 0.5em;
.modal-view-button-arrow {
.modal-view.media-modal-view {
z-index: 9000;
flex-direction: column;
.modal-view-button-arrow,
.modal-view-button-hide {
opacity: 0.75;
&:focus,
@ -67,69 +133,155 @@
outline: none;
box-shadow: none;
}
&:hover {
opacity: 1;
}
}
overflow: hidden;
}
@keyframes media-fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.modal-image {
max-width: 90%;
max-height: 90%;
box-shadow: 0px 5px 15px 0 rgba(0, 0, 0, 0.5);
image-orientation: from-image; // NOTE: only FF supports this
animation: 0.1s cubic-bezier(0.7, 0, 1, 0.6) media-fadein;
}
.modal-view-button-arrow {
position: absolute;
display: block;
top: 50%;
margin-top: -50px;
width: 70px;
height: 100px;
border: 0;
padding: 0;
opacity: 0;
box-shadow: none;
background: none;
appearance: none;
overflow: visible;
cursor: pointer;
transition: opacity 333ms cubic-bezier(.4,0,.22,1);
.arrow-icon {
position: absolute;
top: 35px;
height: 30px;
width: 32px;
font-size: 14px;
line-height: 30px;
color: #FFF;
text-align: center;
background-color: rgba(0,0,0,.3);
}
&--prev {
left: 0;
.arrow-icon {
left: 6px;
.media-modal-view {
@keyframes media-fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
&--next {
right: 0;
.modal-image-container {
display: flex;
overflow: hidden;
align-items: center;
flex-direction: column;
max-width: 100%;
max-height: 100%;
width: 100%;
height: 100%;
flex-grow: 1;
justify-content: center;
&-inner {
width: 100%;
height: 100%;
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
.description,
.counter {
/* Hardcoded since background is also hardcoded */
color: white;
margin-top: 1em;
text-shadow: 0 0 10px black, 0 0 10px black;
padding: 0.2em 2em;
}
.description {
flex: 0 0 auto;
overflow-y: auto;
min-height: 1em;
max-width: 500px;
max-height: 9.5em;
word-break: break-word;
white-space: pre-line;
}
.modal-image {
max-width: 100%;
max-height: 100%;
image-orientation: from-image; // NOTE: only FF supports this
animation: 0.1s cubic-bezier(0.7, 0, 1, 0.6) media-fadein;
&.loading {
opacity: 0.5;
}
}
.loading-spinner {
width: 100%;
height: 100%;
position: absolute;
pointer-events: none;
display: flex;
justify-content: center;
align-items: center;
svg {
color: white;
}
}
.modal-view-button {
border: 0;
padding: 0;
opacity: 0;
box-shadow: none;
background: none;
appearance: none;
overflow: visible;
cursor: pointer;
transition: opacity 333ms cubic-bezier(.4,0,.22,1);
height: $modal-view-button-icon-height;
width: $modal-view-button-icon-width;
.button-icon {
position: absolute;
height: $modal-view-button-icon-height;
width: $modal-view-button-icon-width;
font-size: 1rem;
line-height: $modal-view-button-icon-height;
color: #FFF;
text-align: center;
background-color: rgba(0,0,0,.3);
}
}
.modal-view-button-arrow {
position: absolute;
display: block;
top: 50%;
margin-top: $modal-view-button-icon-half-height;
width: $modal-view-button-icon-width;
height: $modal-view-button-icon-height;
.arrow-icon {
right: 6px;
position: absolute;
top: 0;
line-height: $modal-view-button-icon-height;
color: #FFF;
text-align: center;
background-color: rgba(0,0,0,.3);
}
&--prev {
left: 0;
.arrow-icon {
left: $modal-view-button-icon-margin;
}
}
&--next {
right: 0;
.arrow-icon {
right: $modal-view-button-icon-margin;
}
}
}
.modal-view-button-hide {
position: absolute;
top: 0;
right: 0;
.button-icon {
top: $modal-view-button-icon-margin;
right: $modal-view-button-icon-margin;
}
}
}

View file

@ -17,9 +17,9 @@
/>
<input
v-if="uploadReady"
class="hidden-input-file"
:disabled="disabled"
type="file"
style="position: fixed; top: -100em"
multiple="true"
@change="change"
>
@ -32,6 +32,10 @@
@import '../../_variables.scss';
.media-upload {
cursor: pointer;
cursor: pointer; // We use <label> for interactivity... i wonder if it's fine
.hidden-input-file {
display: none;
}
}
</style>

View file

@ -0,0 +1,134 @@
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { mapGetters, mapState } from 'vuex'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import UserAvatar from '../user_avatar/user_avatar.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAt
} from '@fortawesome/free-solid-svg-icons'
library.add(
faAt
)
const MentionLink = {
name: 'MentionLink',
components: {
UserAvatar
},
props: {
url: {
required: true,
type: String
},
content: {
required: true,
type: String
},
userId: {
required: false,
type: String
},
userScreenName: {
required: false,
type: String
}
},
methods: {
onClick () {
const link = generateProfileLink(
this.userId || this.user.id,
this.userScreenName || this.user.screen_name
)
this.$router.push(link)
}
},
computed: {
user () {
return this.url && this.$store && this.$store.getters.findUserByUrl(this.url)
},
isYou () {
// FIXME why user !== currentUser???
return this.user && this.user.id === this.currentUser.id
},
userName () {
return this.user && this.userNameFullUi.split('@')[0]
},
serverName () {
// XXX assumed that domain does not contain @
return this.user && (this.userNameFullUi.split('@')[1] || this.$store.getters.instanceDomain)
},
userNameFull () {
return this.user && this.user.screen_name
},
userNameFullUi () {
return this.user && this.user.screen_name_ui
},
highlight () {
return this.user && this.mergedConfig.highlight[this.user.screen_name]
},
highlightType () {
return this.highlight && ('-' + this.highlight.type)
},
highlightClass () {
if (this.highlight) return highlightClass(this.user)
},
style () {
if (this.highlight) {
const {
backgroundColor,
backgroundPosition,
backgroundImage,
...rest
} = highlightStyle(this.highlight)
return rest
}
},
classnames () {
return [
{
'-you': this.isYou && this.shouldBoldenYou,
'-highlighted': this.highlight
},
this.highlightType
]
},
useAtIcon () {
return this.mergedConfig.useAtIcon
},
isRemote () {
return this.userName !== this.userNameFull
},
shouldShowFullUserName () {
const conf = this.mergedConfig.mentionLinkDisplay
if (conf === 'short') {
return false
} else if (conf === 'full') {
return true
} else { // full_for_remote
return this.isRemote
}
},
shouldShowTooltip () {
return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote
},
shouldShowAvatar () {
return this.mergedConfig.mentionLinkShowAvatar
},
shouldShowYous () {
return this.mergedConfig.mentionLinkShowYous
},
shouldBoldenYou () {
return this.mergedConfig.mentionLinkBoldenYou
},
shouldFadeDomain () {
return this.mergedConfig.mentionLinkFadeDomain
},
...mapGetters(['mergedConfig']),
...mapState({
currentUser: state => state.users.currentUser
})
}
}
export default MentionLink

View file

@ -0,0 +1,115 @@
@import '../../_variables.scss';
.MentionLink {
position: relative;
white-space: normal;
display: inline;
color: var(--link);
word-break: normal;
& .new,
& .original {
display: inline;
border-radius: 2px;
}
.mention-avatar {
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
width: 1.5em;
height: 1.5em;
vertical-align: middle;
user-select: none;
margin-right: 0.2em;
}
.full {
position: absolute;
display: inline-block;
pointer-events: none;
opacity: 0;
top: 100%;
left: 0;
height: 100%;
word-wrap: normal;
white-space: nowrap;
transition: opacity 0.2s ease;
z-index: 1;
margin-top: 0.25em;
padding: 0.5em;
user-select: all;
}
& .short.-with-tooltip,
& .you {
user-select: none;
}
& .short,
& .full {
white-space: nowrap;
}
.shortName {
white-space: normal;
}
.new {
&.-you {
& .shortName,
& .full {
//font-weight: 600;
}
}
.at {
color: var(--link);
opacity: 0.8;
display: inline-block;
line-height: 1;
padding: 0 0.1em;
vertical-align: -25%;
margin: 0;
}
&.-striped {
& .shortName,
& .full {
background-image:
repeating-linear-gradient(
135deg,
var(--____highlight-tintColor),
var(--____highlight-tintColor) 5px,
var(--____highlight-tintColor2) 5px,
var(--____highlight-tintColor2) 10px
);
}
}
&.-solid {
& .shortName,
& .full {
background-image: linear-gradient(var(--____highlight-tintColor2), var(--____highlight-tintColor2));
}
}
&.-side {
& .shortName,
& .userNameFull {
box-shadow: 0 -5px 3px -4px inset var(--____highlight-solidColor);
}
}
}
&:hover .new .full {
opacity: 1;
pointer-events: initial;
}
.serverName.-faded {
color: var(--faintLink, $fallback--link);
}
.full .-faded {
color: var(--faint, $fallback--faint);
}
}

View file

@ -0,0 +1,66 @@
<template>
<span
class="MentionLink"
>
<!-- eslint-disable vue/no-v-html -->
<a
v-if="!user"
:href="url"
class="original"
target="_blank"
v-html="content"
/><!-- eslint-enable vue/no-v-html --><span
v-if="user"
class="new"
:style="style"
:class="classnames"
>
<a
class="short button-unstyled"
:class="{ '-with-tooltip': shouldShowTooltip }"
:href="url"
@click.prevent="onClick"
>
<!-- eslint-disable vue/no-v-html -->
<span class="shortName">@<span
class="userName"
v-html="userName"
/><span
v-if="shouldShowFullUserName"
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
</span>
<span
v-if="isYou && shouldShowYous"
:class="{ '-you': shouldBoldenYou }"
> {{ ' ' + $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html -->
</a><span
v-if="shouldShowTooltip"
class="full popover-default"
:class="[highlightType]"
>
<span
class="userNameFull"
>
<!-- eslint-disable vue/no-v-html -->
@<span
class="userName"
v-html="userName"
/><span
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
<!-- eslint-enable vue/no-v-html -->
</span>
</span>
</span>
</span>
</template>
<script src="./mention_link.js"/>
<style lang="scss" src="./mention_link.scss"/>

View file

@ -0,0 +1,37 @@
import MentionLink from 'src/components/mention_link/mention_link.vue'
import { mapGetters } from 'vuex'
export const MENTIONS_LIMIT = 5
const MentionsLine = {
name: 'MentionsLine',
props: {
mentions: {
required: true,
type: Array
}
},
data: () => ({ expanded: false }),
components: {
MentionLink
},
computed: {
mentionsComputed () {
return this.mentions.slice(0, MENTIONS_LIMIT)
},
extraMentions () {
return this.mentions.slice(MENTIONS_LIMIT)
},
manyMentions () {
return this.extraMentions.length > 0
},
...mapGetters(['mergedConfig'])
},
methods: {
toggleShowMore () {
this.expanded = !this.expanded
}
}
}
export default MentionsLine

View file

@ -0,0 +1,13 @@
.MentionsLine {
word-break: break-all;
.mention-link:not(:first-child)::before {
content: ' ';
}
.showMoreLess {
margin-left: 0.5em;
white-space: normal;
color: var(--link);
}
}

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