mirror of https://framagit.org/tykayn/mastodon.git
Merge branch 'master' of https://github.com/tootsuite/mastodon 24 dec 2020
This commit is contained in:
commit
c1ce0d49c8
81
AUTHORS.md
81
AUTHORS.md
|
@ -5,38 +5,39 @@ Mastodon is available on [GitHub](https://github.com/tootsuite/mastodon)
|
|||
and provided thanks to the work of the following contributors:
|
||||
|
||||
* [Gargron](https://github.com/Gargron)
|
||||
* [dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
|
||||
* [ThibG](https://github.com/ThibG)
|
||||
* [ykzts](https://github.com/ykzts)
|
||||
* [dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
|
||||
* [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
* [ykzts](https://github.com/ykzts)
|
||||
* [akihikodaki](https://github.com/akihikodaki)
|
||||
* [mjankowski](https://github.com/mjankowski)
|
||||
* [unarist](https://github.com/unarist)
|
||||
* [yiskah](https://github.com/yiskah)
|
||||
* [nolanlawson](https://github.com/nolanlawson)
|
||||
* [abcang](https://github.com/abcang)
|
||||
* [ysksn](https://github.com/ysksn)
|
||||
* [mayaeh](https://github.com/mayaeh)
|
||||
* [ysksn](https://github.com/ysksn)
|
||||
* [sorin-davidoi](https://github.com/sorin-davidoi)
|
||||
* [noellabo](https://github.com/noellabo)
|
||||
* [lynlynlynx](https://github.com/lynlynlynx)
|
||||
* [m4sk1n](mailto:me@m4sk.in)
|
||||
* [Marcin Mikołajczak](mailto:me@m4sk.in)
|
||||
* [Kjwon15](https://github.com/Kjwon15)
|
||||
* [noellabo](https://github.com/noellabo)
|
||||
* [renatolond](https://github.com/renatolond)
|
||||
* [alpaca-tc](https://github.com/alpaca-tc)
|
||||
* [jeroenpraat](https://github.com/jeroenpraat)
|
||||
* [nclm](https://github.com/nclm)
|
||||
* [ineffyble](https://github.com/ineffyble)
|
||||
* [shleeable](https://github.com/shleeable)
|
||||
* [zunda](https://github.com/zunda)
|
||||
* [shleeable](https://github.com/shleeable)
|
||||
* [Masoud Abkenar](mailto:ampbox@gmail.com)
|
||||
* [blackle](https://github.com/blackle)
|
||||
* [Quent-in](https://github.com/Quent-in)
|
||||
* [JantsoP](https://github.com/JantsoP)
|
||||
* [nullkal](https://github.com/nullkal)
|
||||
* [yookoala](https://github.com/yookoala)
|
||||
* [Sasha-Sorokin](https://github.com/Sasha-Sorokin)
|
||||
* [Brawaru](https://github.com/Brawaru)
|
||||
* [ariasuni](https://github.com/ariasuni)
|
||||
* [Aditoo17](https://github.com/Aditoo17)
|
||||
* [Quenty31](https://github.com/Quenty31)
|
||||
* [marek-lach](https://github.com/marek-lach)
|
||||
|
@ -45,7 +46,6 @@ and provided thanks to the work of the following contributors:
|
|||
* [danhunsaker](https://github.com/danhunsaker)
|
||||
* [eramdam](https://github.com/eramdam)
|
||||
* [takayamaki](https://github.com/takayamaki)
|
||||
* [ariasuni](https://github.com/ariasuni)
|
||||
* [masarakki](https://github.com/masarakki)
|
||||
* [ticky](https://github.com/ticky)
|
||||
* [ThisIsMissEm](https://github.com/ThisIsMissEm)
|
||||
|
@ -53,14 +53,15 @@ and provided thanks to the work of the following contributors:
|
|||
* [hcmiya](https://github.com/hcmiya)
|
||||
* [stephenburgess8](https://github.com/stephenburgess8)
|
||||
* [Wonderfall](mailto:wonderfall@targaryen.house)
|
||||
* [trwnh](https://github.com/trwnh)
|
||||
* [matteoaquila](https://github.com/matteoaquila)
|
||||
* [yukimochi](https://github.com/yukimochi)
|
||||
* [palindromordnilap](https://github.com/palindromordnilap)
|
||||
* [rkarabut](https://github.com/rkarabut)
|
||||
* [trwnh](https://github.com/trwnh)
|
||||
* [nightpool](https://github.com/nightpool)
|
||||
* [Artoria2e5](https://github.com/Artoria2e5)
|
||||
* [marrus-sh](https://github.com/marrus-sh)
|
||||
* [dunn](https://github.com/dunn)
|
||||
* [krainboltgreene](https://github.com/krainboltgreene)
|
||||
* [pfigel](https://github.com/pfigel)
|
||||
* [BoFFire](https://github.com/BoFFire)
|
||||
|
@ -84,25 +85,25 @@ and provided thanks to the work of the following contributors:
|
|||
* [ashleyhull-versent](https://github.com/ashleyhull-versent)
|
||||
* [yhirano55](https://github.com/yhirano55)
|
||||
* [rinsuki](https://github.com/rinsuki)
|
||||
* [dunn](https://github.com/dunn)
|
||||
* [devkral](https://github.com/devkral)
|
||||
* [camponez](https://github.com/camponez)
|
||||
* [hugogameiro](https://github.com/hugogameiro)
|
||||
* [SerCom_KC](mailto:szescxz@gmail.com)
|
||||
* [aschmitz](https://github.com/aschmitz)
|
||||
* [mfmfuyu](https://github.com/mfmfuyu)
|
||||
* [kedamaDQ](https://github.com/kedamaDQ)
|
||||
* [fpiesche](https://github.com/fpiesche)
|
||||
* [gandaro](https://github.com/gandaro)
|
||||
* [johnsudaar](https://github.com/johnsudaar)
|
||||
* [trebmuh](https://github.com/trebmuh)
|
||||
* [rmhasan](https://github.com/rmhasan)
|
||||
* [kedamaDQ](https://github.com/kedamaDQ)
|
||||
* [lindwurm](https://github.com/lindwurm)
|
||||
* [victorhck](mailto:victorhck@geeko.site)
|
||||
* [voidsatisfaction](https://github.com/voidsatisfaction)
|
||||
* [mkljczk](https://github.com/mkljczk)
|
||||
* [hikari-no-yume](https://github.com/hikari-no-yume)
|
||||
* [seefood](https://github.com/seefood)
|
||||
* [jackjennings](https://github.com/jackjennings)
|
||||
* [mfmfuyu](https://github.com/mfmfuyu)
|
||||
* [puckipedia](https://github.com/puckipedia)
|
||||
* [spla](mailto:spla@mastodont.cat)
|
||||
* [walf443](https://github.com/walf443)
|
||||
|
@ -111,14 +112,15 @@ and provided thanks to the work of the following contributors:
|
|||
* [Ashley](mailto:expenses@airmail.cc)
|
||||
* [xqus](https://github.com/xqus)
|
||||
* [pfm-eyesightjp](https://github.com/pfm-eyesightjp)
|
||||
* [Samy KACIMI](mailto:samy.kacimi@gmail.com)
|
||||
* [fakenine](https://github.com/fakenine)
|
||||
* [tsuwatch](https://github.com/tsuwatch)
|
||||
* [victorhck](https://github.com/victorhck)
|
||||
* [mkljczk](https://github.com/mkljczk)
|
||||
* [manuelviens](https://github.com/manuelviens)
|
||||
* [tateisu](https://github.com/tateisu)
|
||||
* [fvh-P](https://github.com/fvh-P)
|
||||
* [rtucker](https://github.com/rtucker)
|
||||
* [Anna e só](mailto:contraexemplos@gmail.com)
|
||||
* [dariusk](https://github.com/dariusk)
|
||||
* [kazu9su](https://github.com/kazu9su)
|
||||
* [Komic](https://github.com/Komic)
|
||||
* [lmorchard](https://github.com/lmorchard)
|
||||
|
@ -145,9 +147,9 @@ and provided thanks to the work of the following contributors:
|
|||
* [fhemberger](https://github.com/fhemberger)
|
||||
* [Gomasy](https://github.com/Gomasy)
|
||||
* [greysteil](https://github.com/greysteil)
|
||||
* [hencatsmith](https://github.com/hencatsmith)
|
||||
* [hendotcat](https://github.com/hendotcat)
|
||||
* [d6rkaiz](https://github.com/d6rkaiz)
|
||||
* [Reverite](https://github.com/Reverite)
|
||||
* [ladyisatis](https://github.com/ladyisatis)
|
||||
* [JohnD28](https://github.com/JohnD28)
|
||||
* [znz](https://github.com/znz)
|
||||
* [saper](https://github.com/saper)
|
||||
|
@ -160,14 +162,14 @@ and provided thanks to the work of the following contributors:
|
|||
* [leopku](https://github.com/leopku)
|
||||
* [SansPseudoFix](https://github.com/SansPseudoFix)
|
||||
* [spla](mailto:sp@mastodont.cat)
|
||||
* [tateisu](https://github.com/tateisu)
|
||||
* [tomfhowe](https://github.com/tomfhowe)
|
||||
* [noraworld](https://github.com/noraworld)
|
||||
* [lfuelling](https://github.com/lfuelling)
|
||||
* [theboss](https://github.com/theboss)
|
||||
* [aji-su](https://github.com/aji-su)
|
||||
* [nzws](https://github.com/nzws)
|
||||
* [duxovni](https://github.com/duxovni)
|
||||
* [smorimoto](https://github.com/smorimoto)
|
||||
* [mashirozx](https://github.com/mashirozx)
|
||||
* [178inaba](https://github.com/178inaba)
|
||||
* [acid-chicken](https://github.com/acid-chicken)
|
||||
* [xgess](https://github.com/xgess)
|
||||
|
@ -175,7 +177,6 @@ and provided thanks to the work of the following contributors:
|
|||
* [aablinov](https://github.com/aablinov)
|
||||
* [stalker314314](https://github.com/stalker314314)
|
||||
* [cutls](https://github.com/cutls)
|
||||
* [dariusk](https://github.com/dariusk)
|
||||
* [huertanix](https://github.com/huertanix)
|
||||
* [eleboucher](https://github.com/eleboucher)
|
||||
* [halkeye](https://github.com/halkeye)
|
||||
|
@ -183,7 +184,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [treby](https://github.com/treby)
|
||||
* [jpdevries](https://github.com/jpdevries)
|
||||
* [gdpelican](https://github.com/gdpelican)
|
||||
* [kmichl](https://github.com/kmichl)
|
||||
* [Korbinian](mailto:kontakt@korbinian-michl.de)
|
||||
* [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name)
|
||||
* [panarom](https://github.com/panarom)
|
||||
* [Dar13](https://github.com/Dar13)
|
||||
|
@ -225,6 +226,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [aaribaud](https://github.com/aaribaud)
|
||||
* [pointlessone](https://github.com/pointlessone)
|
||||
* [Andrew](mailto:andrewlchronister@gmail.com)
|
||||
* [arielrodrigues](https://github.com/arielrodrigues)
|
||||
* [aurelien-reeves](https://github.com/aurelien-reeves)
|
||||
* [elegaanz](https://github.com/elegaanz)
|
||||
* [estuans](https://github.com/estuans)
|
||||
|
@ -238,6 +240,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [muffinista](https://github.com/muffinista)
|
||||
* [cdutson](https://github.com/cdutson)
|
||||
* [farlistener](https://github.com/farlistener)
|
||||
* [divergentdave](https://github.com/divergentdave)
|
||||
* [DavidLibeau](https://github.com/DavidLibeau)
|
||||
* [dmerejkowsky](https://github.com/dmerejkowsky)
|
||||
* [ddevault](https://github.com/ddevault)
|
||||
|
@ -276,7 +279,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [xPaw](https://github.com/xPaw)
|
||||
* [petzah](https://github.com/petzah)
|
||||
* [ignisf](https://github.com/ignisf)
|
||||
* [raymestalez](https://github.com/raymestalez)
|
||||
* [lumenwrites](https://github.com/lumenwrites)
|
||||
* [remram44](https://github.com/remram44)
|
||||
* [sts10](https://github.com/sts10)
|
||||
* [SuperSandro2000](https://github.com/SuperSandro2000)
|
||||
|
@ -286,8 +289,9 @@ and provided thanks to the work of the following contributors:
|
|||
* [Sir-Boops](https://github.com/Sir-Boops)
|
||||
* [stemid](https://github.com/stemid)
|
||||
* [sumdog](https://github.com/sumdog)
|
||||
* [OmmyZhang](https://github.com/OmmyZhang)
|
||||
* [ThomasLeister](https://github.com/ThomasLeister)
|
||||
* [mcat-ee](https://github.com/mcat-ee)
|
||||
* [Tom McAtee](mailto:a1608768@student.adelaide.edu.au)
|
||||
* [tototoshi](https://github.com/tototoshi)
|
||||
* [TrashMacNugget](https://github.com/TrashMacNugget)
|
||||
* [VirtuBox](https://github.com/VirtuBox)
|
||||
|
@ -314,11 +318,13 @@ and provided thanks to the work of the following contributors:
|
|||
* [matsurai25](https://github.com/matsurai25)
|
||||
* [mecab](https://github.com/mecab)
|
||||
* [nicobz25](https://github.com/nicobz25)
|
||||
* [niwatori24](https://github.com/niwatori24)
|
||||
* [oliverkeeble](https://github.com/oliverkeeble)
|
||||
* [partev](https://github.com/partev)
|
||||
* [pinfort](https://github.com/pinfort)
|
||||
* [rbaumert](https://github.com/rbaumert)
|
||||
* [rhoio](https://github.com/rhoio)
|
||||
* [santiagorodriguez96](https://github.com/santiagorodriguez96)
|
||||
* [sclaire-1](https://github.com/sclaire-1)
|
||||
* [umonaca](https://github.com/umonaca)
|
||||
* [usagi-f](https://github.com/usagi-f)
|
||||
|
@ -327,7 +333,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [wxcafe](https://github.com/wxcafe)
|
||||
* [Grawl](https://github.com/Grawl)
|
||||
* [新都心(Neet Shin)](mailto:nucx@dio-vox.com)
|
||||
* [clarfon](https://github.com/clarfon)
|
||||
* [clarfonthey](https://github.com/clarfonthey)
|
||||
* [cygnan](https://github.com/cygnan)
|
||||
* [Awea](https://github.com/Awea)
|
||||
* [eai04191](https://github.com/eai04191)
|
||||
|
@ -358,11 +364,11 @@ and provided thanks to the work of the following contributors:
|
|||
* [schas002](https://github.com/schas002)
|
||||
* [contraexemplo](https://github.com/contraexemplo)
|
||||
* [abackstrom](https://github.com/abackstrom)
|
||||
* [arielrodrigues](https://github.com/arielrodrigues)
|
||||
* [orlea](https://github.com/orlea)
|
||||
* [armandfardeau](https://github.com/armandfardeau)
|
||||
* [raboof](https://github.com/raboof)
|
||||
* [jumbosushi](https://github.com/jumbosushi)
|
||||
* [acuteaura](https://github.com/acuteaura)
|
||||
* [ayumin](https://github.com/ayumin)
|
||||
* [bzg](https://github.com/bzg)
|
||||
* [BastienDurel](https://github.com/BastienDurel)
|
||||
|
@ -389,7 +395,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [colindean](https://github.com/colindean)
|
||||
* [DeeUnderscore](https://github.com/DeeUnderscore)
|
||||
* [dachinat](https://github.com/dachinat)
|
||||
* [shapeshifter-system](https://github.com/shapeshifter-system)
|
||||
* [monsterpit-firedemon](https://github.com/monsterpit-firedemon)
|
||||
* [watilde](https://github.com/watilde)
|
||||
* [daprice](https://github.com/daprice)
|
||||
* [da2x](https://github.com/da2x)
|
||||
|
@ -400,14 +406,13 @@ and provided thanks to the work of the following contributors:
|
|||
* [singingwolfboy](https://github.com/singingwolfboy)
|
||||
* [caldwell](https://github.com/caldwell)
|
||||
* [davidcelis](https://github.com/davidcelis)
|
||||
* [divergentdave](https://github.com/divergentdave)
|
||||
* [davefp](https://github.com/davefp)
|
||||
* [yipdw](https://github.com/yipdw)
|
||||
* [debanshuk](https://github.com/debanshuk)
|
||||
* [mascali33](https://github.com/mascali33)
|
||||
* [DerekNonGeneric](https://github.com/DerekNonGeneric)
|
||||
* [dblandin](https://github.com/dblandin)
|
||||
* [Drew Gates](mailto:aranaur@users.noreply.github.com)
|
||||
* [Aranaur](https://github.com/Aranaur)
|
||||
* [dtschust](https://github.com/dtschust)
|
||||
* [Dryusdan](https://github.com/Dryusdan)
|
||||
* [d3vgru](https://github.com/d3vgru)
|
||||
|
@ -451,22 +456,25 @@ and provided thanks to the work of the following contributors:
|
|||
* [J Yeary](mailto:usbsnowcrash@users.noreply.github.com)
|
||||
* [jack-michaud](https://github.com/jack-michaud)
|
||||
* [Floppy](https://github.com/Floppy)
|
||||
* [loomchild](https://github.com/loomchild)
|
||||
* [jglauche](https://github.com/jglauche)
|
||||
* [jenkr55](https://github.com/jenkr55)
|
||||
* [hyenagirl64](https://github.com/hyenagirl64)
|
||||
* [press5](https://github.com/press5)
|
||||
* [TrollDecker](https://github.com/TrollDecker)
|
||||
* [jmontane](https://github.com/jmontane)
|
||||
* [Jarek Lipski](mailto:pub@loomchild.net)
|
||||
* [Jennifer Glauche](mailto:=^.^=@github19.jglauche.de)
|
||||
* [Jennifer Kruse](mailto:jenkr55@gmail.com)
|
||||
* [Jeremy Rose](mailto:nornagon@nornagon.net)
|
||||
* [Jessica](mailto:46502909+hyenagirl64@users.noreply.github.com)
|
||||
* [Jessica K. Litwin](mailto:jessica@litw.in)
|
||||
* [Jo Decker](mailto:trolldecker@users.noreply.github.com)
|
||||
* [Joan Montané](mailto:jmontane@users.noreply.github.com)
|
||||
* [Jonathan Klee](mailto:klee.jonathan@gmail.com)
|
||||
* [Jordan Guerder](mailto:jguerder@fr.pulseheberg.net)
|
||||
* [Joseph Mingrone](mailto:jehops@users.noreply.github.com)
|
||||
* [Josh Leeb-du Toit](mailto:mail@joshleeb.com)
|
||||
* [Joshua Wood](mailto:josh@joshuawood.net)
|
||||
* [Julien](mailto:tiwy57@users.noreply.github.com)
|
||||
* [Julien Deswaef](mailto:juego@requiem4tv.com)
|
||||
* [June Sallou](mailto:jnsll@users.noreply.github.com)
|
||||
* [Jérémy Benoist](mailto:j0k3r@users.noreply.github.com)
|
||||
* [KEINOS](mailto:github@keinos.com)
|
||||
* [Kairui Song | 宋恺睿](mailto:ryncsn@gmail.com)
|
||||
* [Keiji Matsuzaki](mailto:futoase@gmail.com)
|
||||
* [Kevin Liu](mailto:kevin@potatofrom.space)
|
||||
* [Kit Redgrave](mailto:qwertyitis@gmail.com)
|
||||
|
@ -482,7 +490,6 @@ and provided thanks to the work of the following contributors:
|
|||
* [Lukas Burk](mailto:jemus42@users.noreply.github.com)
|
||||
* [Manato Kameya](mailto:grabacr07+github@gmail.com)
|
||||
* [Mantas](mailto:mistermantas@users.noreply.github.com)
|
||||
* [Marcin Mikołajczak](mailto:me@mkljczk.pl)
|
||||
* [Mareena Kunjachan](mailto:mareenakunjachan@gmail.com)
|
||||
* [Marek Lach](mailto:marek.brohatwack.lach@gmail.com)
|
||||
* [Markus R](mailto:wirehack7@users.noreply.github.com)
|
||||
|
@ -529,10 +536,12 @@ and provided thanks to the work of the following contributors:
|
|||
* [Norayr Chilingarian](mailto:norayr@arnet.am)
|
||||
* [Noëlle Anthony](mailto:noelle.d.anthony@gmail.com)
|
||||
* [N氏](mailto:uenok.htc@gmail.com)
|
||||
* [OSAMU SATO](mailto:satosamu@gmail.com)
|
||||
* [Olivier Nicole](mailto:olivierthnicole@gmail.com)
|
||||
* [Oskari Noppa](mailto:noppa@users.noreply.github.com)
|
||||
* [Otakan](mailto:otakan951@gmail.com)
|
||||
* [Padraig Fahy](mailto:tech@padraigfahy.com)
|
||||
* [Patrice Ferlet](mailto:metal3d@gmail.com)
|
||||
* [PatrickRWells](mailto:32802366+patrickrwells@users.noreply.github.com)
|
||||
* [Paul](mailto:naydex.mc+github@gmail.com)
|
||||
* [Pete Keen](mailto:pete@petekeen.net)
|
||||
|
@ -574,7 +583,6 @@ and provided thanks to the work of the following contributors:
|
|||
* [TakesxiSximada](mailto:takesxi.sximada@gmail.com)
|
||||
* [Tao Bror Bojlén](mailto:brortao@users.noreply.github.com)
|
||||
* [Taras Gogol](mailto:taras2358@gmail.com)
|
||||
* [Tdxdxoz](mailto:tdxdxoz@gmail.com)
|
||||
* [TheInventrix](mailto:theinventrix@users.noreply.github.com)
|
||||
* [TheMainOne](mailto:50847364+theevilskeleton@users.noreply.github.com)
|
||||
* [Thomas Alberola](mailto:thomas@needacoffee.fr)
|
||||
|
@ -594,6 +602,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [Wesley Ellis](mailto:tahnok@gmail.com)
|
||||
* [Wiktor](mailto:wiktor@metacode.biz)
|
||||
* [Wonderfall](mailto:wonderfall@schrodinger.io)
|
||||
* [Y.Yamashiro](mailto:shukukei@mojizuri.jp)
|
||||
* [YDrogen](mailto:ydrogen45@gmail.com)
|
||||
* [YMHuang](mailto:ymhuang@fmbase.tw)
|
||||
* [YOSHIOKA Eiichiro](mailto:yoshioka.eiichiro@gmail.com)
|
||||
|
@ -638,6 +647,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [jumoru](mailto:jumoru@mailbox.org)
|
||||
* [kaiyou](mailto:pierre@jaury.eu)
|
||||
* [karlyeurl](mailto:karl.yeurl@gmail.com)
|
||||
* [kawaguchi](mailto:jiikko@users.noreply.github.com)
|
||||
* [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
|
||||
* [kuro5hin](mailto:rusty@kuro5hin.org)
|
||||
* [leo60228](mailto:leo@60228.dev)
|
||||
|
@ -655,6 +665,7 @@ and provided thanks to the work of the following contributors:
|
|||
* [notozeki](mailto:notozeki@users.noreply.github.com)
|
||||
* [ntl-purism](mailto:57806346+ntl-purism@users.noreply.github.com)
|
||||
* [nzws](mailto:git-yuzu@svk.jp)
|
||||
* [proxy](mailto:51172302+3n-k1@users.noreply.github.com)
|
||||
* [rch850](mailto:rich850@gmail.com)
|
||||
* [roikale](mailto:roikale@users.noreply.github.com)
|
||||
* [rysiekpl](mailto:rysiek@hackerspace.pl)
|
||||
|
|
231
CHANGELOG.md
231
CHANGELOG.md
|
@ -3,6 +3,237 @@ Changelog
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
### Added
|
||||
|
||||
- **Add hotkeys for audio/video control in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15158), [Gargron](https://github.com/tootsuite/mastodon/pull/15198))
|
||||
- `Space` and `k` to toggle playback
|
||||
- `m` to toggle mute
|
||||
- `f` to toggle fullscreen
|
||||
- `j` and `l` to go back and forward by 10 seconds
|
||||
- `.` and `,` to go back and forward by a frame (video only)
|
||||
- Add expand/compress button on media modal in web UI ([mashirozx](https://github.com/tootsuite/mastodon/pull/15068), [mashirozx](https://github.com/tootsuite/mastodon/pull/15088), [mashirozx](https://github.com/tootsuite/mastodon/pull/15094))
|
||||
- Add border around 🕺 emoji in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14769))
|
||||
- Add border around 🐞 emoji in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14712))
|
||||
- Add home link to the getting started column when home isn't mounted ([ThibG](https://github.com/tootsuite/mastodon/pull/14707))
|
||||
- Add option to disable swiping motions across the web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13885))
|
||||
- **Add pop-out player for audio/video in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/14870), [Gargron](https://github.com/tootsuite/mastodon/pull/15157), [Gargron](https://github.com/tootsuite/mastodon/pull/14915), [noellabo](https://github.com/tootsuite/mastodon/pull/15309))
|
||||
- Continue watching/listening when you scroll away
|
||||
- Action bar to interact with/open toot from the pop-out player
|
||||
- Add unread notification markers in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14818), [ThibG](https://github.com/tootsuite/mastodon/pull/14960), [ThibG](https://github.com/tootsuite/mastodon/pull/14954), [noellabo](https://github.com/tootsuite/mastodon/pull/14897), [noellabo](https://github.com/tootsuite/mastodon/pull/14907))
|
||||
- Add paragraph about browser add-ons when encountering errors in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14801))
|
||||
- Add import and export for bookmarks ([ThibG](https://github.com/tootsuite/mastodon/pull/14956))
|
||||
- Add cache buster feature for media files ([Gargron](https://github.com/tootsuite/mastodon/pull/15155))
|
||||
- If you have a proxy cache in front of object storage, deleted files will persist until the cache expires
|
||||
- If enabled, cache buster will make a special request to the proxy to signal a cache reset
|
||||
- Add duration option to the mute function ([aquarla](https://github.com/tootsuite/mastodon/pull/13831))
|
||||
- Add replies policy option to the list function ([ThibG](https://github.com/tootsuite/mastodon/pull/9205), [trwnh](https://github.com/tootsuite/mastodon/pull/15304))
|
||||
- Add `og:published_time` OpenGraph tags on toots ([nornagon](https://github.com/tootsuite/mastodon/pull/14865))
|
||||
- **Add option to be notified when a followed user posts** ([Gargron](https://github.com/tootsuite/mastodon/pull/13546), [ThibG](https://github.com/tootsuite/mastodon/pull/14896), [Gargron](https://github.com/tootsuite/mastodon/pull/14822))
|
||||
- If you don't want to miss a toot, click the bell button!
|
||||
- Add client-side validation in password change forms ([ThibG](https://github.com/tootsuite/mastodon/pull/14564))
|
||||
- Add client-side validation in the registration form ([ThibG](https://github.com/tootsuite/mastodon/pull/14560), [ThibG](https://github.com/tootsuite/mastodon/pull/14599))
|
||||
- Add support for Gemini URLs ([joshleeb](https://github.com/tootsuite/mastodon/pull/15013))
|
||||
- Add app shortcuts to web app manifest ([mkljczk](https://github.com/tootsuite/mastodon/pull/15234))
|
||||
- Add WebAuthn as an alternative 2FA method ([santiagorodriguez96](https://github.com/tootsuite/mastodon/pull/14466), [jiikko](https://github.com/tootsuite/mastodon/pull/14806))
|
||||
- Add honeypot fields and minimum fill-out time for sign-up form ([ThibG](https://github.com/tootsuite/mastodon/pull/15276))
|
||||
- Add icon for mutual relationships in relationship manager ([noellabo](https://github.com/tootsuite/mastodon/pull/15149))
|
||||
- Add follow selected followers button in relationship manager ([noellabo](https://github.com/tootsuite/mastodon/pull/15148))
|
||||
- **Add subresource integrity for JS and CSS assets** ([Gargron](https://github.com/tootsuite/mastodon/pull/15096))
|
||||
- If you use a CDN for static assets (JavaScript, CSS, and so on), you have to trust that the CDN does not modify the assets maliciously
|
||||
- Subresource integrity compares server-generated asset digests with what's actually served from the CDN and prevents such attacks
|
||||
- Add `ku`, `sa`, `sc`, `zgh` to available locales ([ykzts](https://github.com/tootsuite/mastodon/pull/15138))
|
||||
- Add ability to force an account to mark media as sensitive ([noellabo](https://github.com/tootsuite/mastodon/pull/14361))
|
||||
- **Add ability to block access or limit sign-ups from chosen IPs** ([Gargron](https://github.com/tootsuite/mastodon/pull/14963), [ThibG](https://github.com/tootsuite/mastodon/pull/15263))
|
||||
- Add rules for IPs or CIDR ranges that automatically expire after a configurable amount of time
|
||||
- Choose the severity of the rule, either blocking all access or merely limiting sign-ups
|
||||
- **Add support for reversible suspensions through ActivityPub** ([Gargron](https://github.com/tootsuite/mastodon/pull/14989))
|
||||
- Servers can signal that one of their accounts has been suspended
|
||||
- During suspension, the account can only delete its own content
|
||||
- A reversal of the suspension can be signalled the same way
|
||||
- A local suspension always overrides a remote one
|
||||
- Add indication to admin UI of whether a report has been forwarded ([ThibG](https://github.com/tootsuite/mastodon/pull/13237))
|
||||
- Add display of reasons for joining of an account in admin UI ([mashirozx](https://github.com/tootsuite/mastodon/pull/15265))
|
||||
- Add option to obfuscate domain name in public list of domain blocks ([Gargron](https://github.com/tootsuite/mastodon/pull/15355))
|
||||
- Add option to make reasons for joining required on sign-up ([ThibG](https://github.com/tootsuite/mastodon/pull/15326), [ThibG](https://github.com/tootsuite/mastodon/pull/15358), [ThibG](https://github.com/tootsuite/mastodon/pull/15385), [ThibG](https://github.com/tootsuite/mastodon/pull/15405))
|
||||
- Add ActivityPub follower synchronization mechanism ([ThibG](https://github.com/tootsuite/mastodon/pull/14510), [ThibG](https://github.com/tootsuite/mastodon/pull/15026))
|
||||
- Add outbox attribute to instance actor ([ThibG](https://github.com/tootsuite/mastodon/pull/14721))
|
||||
- Add featured hashtags as an ActivityPub collection ([Gargron](https://github.com/tootsuite/mastodon/pull/11595), [noellabo](https://github.com/tootsuite/mastodon/pull/15277))
|
||||
- Add support for dereferencing objects through bearcaps ([Gargron](https://github.com/tootsuite/mastodon/pull/14683), [noellabo](https://github.com/tootsuite/mastodon/pull/14981))
|
||||
- Add `S3_READ_TIMEOUT` environment variable ([tateisu](https://github.com/tootsuite/mastodon/pull/14952))
|
||||
- Add `ALLOWED_PRIVATE_ADDRESSES` environment variable ([ThibG](https://github.com/tootsuite/mastodon/pull/14722))
|
||||
- Add `--fix-permissions` option to `tootctl media remove-orphans` ([Gargron](https://github.com/tootsuite/mastodon/pull/14383), [uist1idrju3i](https://github.com/tootsuite/mastodon/pull/14715))
|
||||
- Add `tootctl accounts merge` ([Gargron](https://github.com/tootsuite/mastodon/pull/15201), [ThibG](https://github.com/tootsuite/mastodon/pull/15264), [ThibG](https://github.com/tootsuite/mastodon/pull/15256))
|
||||
- Has someone changed their domain or subdomain thereby creating two accounts where there should be one?
|
||||
- This command will fix it on your end
|
||||
- Add `tootctl maintenance fix-duplicates` ([ThibG](https://github.com/tootsuite/mastodon/pull/14860), [Gargron](https://github.com/tootsuite/mastodon/pull/15223), [ThibG](https://github.com/tootsuite/mastodon/pull/15373))
|
||||
- Index corruption in the database?
|
||||
- This command is for you
|
||||
- **Add support for managing multiple stream subscriptions in a single connection** ([Gargron](https://github.com/tootsuite/mastodon/pull/14524), [Gargron](https://github.com/tootsuite/mastodon/pull/14566), [mfmfuyu](https://github.com/tootsuite/mastodon/pull/14859), [zunda](https://github.com/tootsuite/mastodon/pull/14608))
|
||||
- Previously, getting live updates for multiple timelines required opening a HTTP or WebSocket connection for each
|
||||
- More connections means more resource consumption on both ends, not to mention the (ever so slight) delay when establishing a new connection
|
||||
- Now, with just a single WebSocket connection you can subscribe and unsubscribe to and from multiple streams
|
||||
- Add support for limiting results by both `min_id` and `max_id` at the same time in REST API ([tateisu](https://github.com/tootsuite/mastodon/pull/14776))
|
||||
- Add `GET /api/v1/accounts/:id/featured_tags` to REST API ([noellabo](https://github.com/tootsuite/mastodon/pull/11817), [noellabo](https://github.com/tootsuite/mastodon/pull/15270))
|
||||
- Add stoplight for object storage failures, return HTTP 503 in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/13043))
|
||||
- Add optional `tootctl remove media` cronjob in Helm chart ([dunn](https://github.com/tootsuite/mastodon/pull/14396))
|
||||
- Add clean error message when `RAILS_ENV` is unset ([ThibG](https://github.com/tootsuite/mastodon/pull/15381))
|
||||
|
||||
### Changed
|
||||
|
||||
- **Change media modals look in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/15217), [Gargron](https://github.com/tootsuite/mastodon/pull/15221), [Gargron](https://github.com/tootsuite/mastodon/pull/15284), [Gargron](https://github.com/tootsuite/mastodon/pull/15283), [Kjwon15](https://github.com/tootsuite/mastodon/pull/15308), [noellabo](https://github.com/tootsuite/mastodon/pull/15305))
|
||||
- Background of the overlay matches the color of the image
|
||||
- Action bar to interact with or open the toot from the modal
|
||||
- Change order of announcements in admin UI to be newest-first ([ThibG](https://github.com/tootsuite/mastodon/pull/15091))
|
||||
- **Change account suspensions to be reversible by default** ([Gargron](https://github.com/tootsuite/mastodon/pull/14726), [ThibG](https://github.com/tootsuite/mastodon/pull/15152), [ThibG](https://github.com/tootsuite/mastodon/pull/15106), [ThibG](https://github.com/tootsuite/mastodon/pull/15100), [ThibG](https://github.com/tootsuite/mastodon/pull/15099), [noellabo](https://github.com/tootsuite/mastodon/pull/14855), [ThibG](https://github.com/tootsuite/mastodon/pull/15380))
|
||||
- Suspensions no longer equal deletions
|
||||
- A suspended account can be unsuspended with minimal consequences for 30 days
|
||||
- Immediate deletion of data is still available as an explicit option
|
||||
- Suspended accounts can request an archive of their data through the UI
|
||||
- Change REST API to return empty data for suspended accounts (14765)
|
||||
- Change web UI to show empty profile for suspended accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/14766), [Gargron](https://github.com/tootsuite/mastodon/pull/15345))
|
||||
- Change featured hashtag suggestions to be recently used instead of most used ([abcang](https://github.com/tootsuite/mastodon/pull/14760))
|
||||
- Change direct toots to appear in the home feed again ([Gargron](https://github.com/tootsuite/mastodon/pull/14711), [ThibG](https://github.com/tootsuite/mastodon/pull/15182), [noellabo](https://github.com/tootsuite/mastodon/pull/14727))
|
||||
- Return to treating all toots the same instead of trying to retrofit direct visibility into an instant messaging model
|
||||
- Change email address validation to return more specific errors ([ThibG](https://github.com/tootsuite/mastodon/pull/14565))
|
||||
- Change HTTP signature requirements to include `Digest` header on `POST` requests ([ThibG](https://github.com/tootsuite/mastodon/pull/15069))
|
||||
- Change click area of video/audio player buttons to be bigger in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/15049))
|
||||
- Change order of filters by alphabetic by "keyword or phrase" ([ariasuni](https://github.com/tootsuite/mastodon/pull/15050))
|
||||
- Change suspension of remote accounts to also undo outgoing follows ([ThibG](https://github.com/tootsuite/mastodon/pull/15188))
|
||||
- Change string "Home" to "Home and lists" in the filter creation screen ([ariasuni](https://github.com/tootsuite/mastodon/pull/15139))
|
||||
- Change string "Boost to original audience" to "Boost with original visibility" in web UI ([3n-k1](https://github.com/tootsuite/mastodon/pull/14598))
|
||||
- Change string "Show more" to "Show newer" and "Show older" on public pages ([ariasuni](https://github.com/tootsuite/mastodon/pull/15052))
|
||||
- Change order of announcements to be reverse chronological in web UI ([dariusk](https://github.com/tootsuite/mastodon/pull/15065), [dariusk](https://github.com/tootsuite/mastodon/pull/15070))
|
||||
- Change RTL detection to rely on unicode-bidi paragraph by paragraph in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14573))
|
||||
- Change visibility icon next to timestamp to be clickable in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/15053), [mayaeh](https://github.com/tootsuite/mastodon/pull/15055))
|
||||
- Change public thread view to hide "Show thread" link ([ThibG](https://github.com/tootsuite/mastodon/pull/15266))
|
||||
- Change number format on about page from full to shortened ([Gargron](https://github.com/tootsuite/mastodon/pull/15327))
|
||||
- Change how scheduled tasks run in multi-process environments ([noellabo](https://github.com/tootsuite/mastodon/pull/15314))
|
||||
- New dedicated queue `scheduler`
|
||||
- Runs by default when Sidekiq is executed with no options
|
||||
- Has to be added manually in a multi-process environment
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove fade-in animation from modals in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15199))
|
||||
- Remove auto-redirect to direct messages in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15142))
|
||||
- Remove obsolete IndexedDB operations from web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14730))
|
||||
- Remove dependency on unused and unmaintained http_parser.rb gem ([ThibG](https://github.com/tootsuite/mastodon/pull/14574))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix layout on about page when contact account has a long username ([ThibG](https://github.com/tootsuite/mastodon/pull/15357))
|
||||
- Fix follow limit preventing re-following of a moved account ([Gargron](https://github.com/tootsuite/mastodon/pull/14207))
|
||||
- **Fix deletes not reaching every server that interacted with toot** ([Gargron](https://github.com/tootsuite/mastodon/pull/15200))
|
||||
- Previously, delete of a toot would be primarily sent to the followers of its author, people mentioned in the toot, and people who reblogged the toot
|
||||
- Now, additionally, it is ensured that it is sent to people who replied to it, favourited it, and to the person it replies to even if that person is not mentioned
|
||||
- Fix resolving an account through its non-canonical form (i.e. alternate domain) ([ThibG](https://github.com/tootsuite/mastodon/pull/15187))
|
||||
- Fix sending redundant ActivityPub events when processing remote account deletion ([ThibG](https://github.com/tootsuite/mastodon/pull/15104))
|
||||
- Fix Move handler not being triggered when failing to fetch target account ([ThibG](https://github.com/tootsuite/mastodon/pull/15107))
|
||||
- Fix downloading remote media files when server returns empty filename ([ThibG](https://github.com/tootsuite/mastodon/pull/14867))
|
||||
- Fix account processing failing because of large collections ([ThibG](https://github.com/tootsuite/mastodon/pull/15027))
|
||||
- Fix not being able to unfavorite toots one has lost access to ([ThibG](https://github.com/tootsuite/mastodon/pull/15192))
|
||||
- Fix not being able to unbookmark toots one has lost access to ([ThibG](https://github.com/tootsuite/mastodon/pull/14604))
|
||||
- Fix possible casing inconsistencies in hashtag search ([ThibG](https://github.com/tootsuite/mastodon/pull/14906))
|
||||
- Fix updating account counters when association is not yet created ([Gargron](https://github.com/tootsuite/mastodon/pull/15108))
|
||||
- Fix cookies not having a SameSite attribute ([Gargron](https://github.com/tootsuite/mastodon/pull/15098))
|
||||
- Fix poll ending notifications being created for each vote ([ThibG](https://github.com/tootsuite/mastodon/pull/15071))
|
||||
- Fix multiple boosts of a same toot erroneously appearing in TL ([ThibG](https://github.com/tootsuite/mastodon/pull/14759))
|
||||
- Fix asset builds not picking up `CDN_HOST` change ([ThibG](https://github.com/tootsuite/mastodon/pull/14381))
|
||||
- Fix desktop notifications permission prompt in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14985), [Gargron](https://github.com/tootsuite/mastodon/pull/15141), [ThibG](https://github.com/tootsuite/mastodon/pull/13543), [ThibG](https://github.com/tootsuite/mastodon/pull/15176))
|
||||
- Some time ago, browsers added a requirement that desktop notification prompts could only be displayed in response to a user-generated event (such as a click)
|
||||
- This means that for some time, users who haven't already given the permission before were not getting a prompt and as such were not receiving desktop notifications
|
||||
- Fix "Mark media as sensitive" string not supporting pluralizations in other languages in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/15051))
|
||||
- Fix glitched image uploads when canvas read access is blocked in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/15180))
|
||||
- Fix some account gallery items having empty labels in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/15073))
|
||||
- Fix alt-key hotkeys activating while typing in a text field in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14942))
|
||||
- Fix wrong seek bar width on media player in web UI ([mfmfuyu](https://github.com/tootsuite/mastodon/pull/15060))
|
||||
- Fix logging out on mobile in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14901))
|
||||
- Fix wrong click area for GIFVs in media modal in web UI ([noellabo](https://github.com/tootsuite/mastodon/pull/14615))
|
||||
- Fix unreadable placeholder text color in high contrast theme in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/14803))
|
||||
- Fix scrolling issues when closing some dropdown menus in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14606))
|
||||
- Fix notification filter bar incorrectly filtering gaps in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14808))
|
||||
- Fix disabled boost icon being replaced by private boost icon on hover in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14456))
|
||||
- Fix hashtag detection in compose form being different to server-side in web UI ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/14484), [ThibG](https://github.com/tootsuite/mastodon/pull/14513))
|
||||
- Fix home last read marker mishandling gaps in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14809))
|
||||
- Fix unnecessary re-rendering of various components when typing in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15286))
|
||||
- Fix notifications being unnecessarily re-rendered in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/15312))
|
||||
- Fix column swiping animation logic in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/15301))
|
||||
- Fix inefficiency when fetching hashtag timeline ([noellabo](https://github.com/tootsuite/mastodon/pull/14861), [akihikodaki](https://github.com/tootsuite/mastodon/pull/14662))
|
||||
- Fix inefficiency when fetching bookmarks ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14674))
|
||||
- Fix inefficiency when fetching favourites ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14673))
|
||||
- Fix inefficiency when fetching media-only account timeline ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14675))
|
||||
- Fix inefficieny when deleting accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/15387), [ThibG](https://github.com/tootsuite/mastodon/pull/15409), [ThibG](https://github.com/tootsuite/mastodon/pull/15407), [ThibG](https://github.com/tootsuite/mastodon/pull/15408), [ThibG](https://github.com/tootsuite/mastodon/pull/15402))
|
||||
- Fix redundant query when processing batch actions on custom emojis ([niwatori24](https://github.com/tootsuite/mastodon/pull/14534))
|
||||
- Fix slow distinct queries where grouped queries are faster ([Gargron](https://github.com/tootsuite/mastodon/pull/15287))
|
||||
- Fix performance on instances list in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15282))
|
||||
- Fix server actor appearing in list of accounts in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14567))
|
||||
- Fix "bootstrap timeline accounts" toggle in site settings in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/15325))
|
||||
- Fix PostgreSQL secret name for cronjob in Helm chart ([metal3d](https://github.com/tootsuite/mastodon/pull/15072))
|
||||
- Fix Procfile not being compatible with herokuish ([acuteaura](https://github.com/tootsuite/mastodon/pull/12685))
|
||||
- Fix installation of tini being split into multiple steps in Dockerfile ([ryncsn](https://github.com/tootsuite/mastodon/pull/14686))
|
||||
|
||||
### Security
|
||||
|
||||
- Fix streaming API allowing connections to persist after access token invalidation ([Gargron](https://github.com/tootsuite/mastodon/pull/15111))
|
||||
- Fix 2FA/sign-in token sessions being valid after password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14802))
|
||||
- Fix resolving accounts sometimes creating duplicate records for a given ActivityPub identifier ([ThibG](https://github.com/tootsuite/mastodon/pull/15364))
|
||||
|
||||
## [3.2.2] - 2020-12-19
|
||||
### Added
|
||||
|
||||
- Add `tootctl maintenance fix-duplicates` ([ThibG](https://github.com/tootsuite/mastodon/pull/14860), [Gargron](https://github.com/tootsuite/mastodon/pull/15223))
|
||||
- Index corruption in the database?
|
||||
- This command is for you
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove dependency on unused and unmaintained http_parser.rb gem ([ThibG](https://github.com/tootsuite/mastodon/pull/14574))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix Move handler not being triggered when failing to fetch target account ([ThibG](https://github.com/tootsuite/mastodon/pull/15107))
|
||||
- Fix downloading remote media files when server returns empty filename ([ThibG](https://github.com/tootsuite/mastodon/pull/14867))
|
||||
- Fix possible casing inconsistencies in hashtag search ([ThibG](https://github.com/tootsuite/mastodon/pull/14906))
|
||||
- Fix updating account counters when association is not yet created ([Gargron](https://github.com/tootsuite/mastodon/pull/15108))
|
||||
- Fix account processing failing because of large collections ([ThibG](https://github.com/tootsuite/mastodon/pull/15027))
|
||||
- Fix resolving an account through its non-canonical form (i.e. alternate domain) ([ThibG](https://github.com/tootsuite/mastodon/pull/15187))
|
||||
- Fix slow distinct queries where grouped queries are faster ([Gargron](https://github.com/tootsuite/mastodon/pull/15287))
|
||||
|
||||
### Security
|
||||
|
||||
- Fix 2FA/sign-in token sessions being valid after password change ([Gargron](https://github.com/tootsuite/mastodon/pull/14802))
|
||||
- Fix resolving accounts sometimes creating duplicate records for a given ActivityPub identifier ([ThibG](https://github.com/tootsuite/mastodon/pull/15364))
|
||||
|
||||
## [3.2.1] - 2020-10-19
|
||||
### Added
|
||||
|
||||
- Add support for latest HTTP Signatures spec draft ([ThibG](https://github.com/tootsuite/mastodon/pull/14556))
|
||||
- Add support for inlined objects in ActivityPub `to`/`cc` ([ThibG](https://github.com/tootsuite/mastodon/pull/14514))
|
||||
|
||||
### Changed
|
||||
|
||||
- Change actors to not be served at all without authentication in limited federation mode ([ThibG](https://github.com/tootsuite/mastodon/pull/14800))
|
||||
- Previously, a bare version of an actor was served when not authenticated, i.e. username and public key
|
||||
- Because all actor fetch requests are signed using a separate system actor, that is no longer required
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `tootctl media` commands not recognizing very large IDs ([ThibG](https://github.com/tootsuite/mastodon/pull/14536))
|
||||
- Fix crash when failing to load emoji picker in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14525))
|
||||
- Fix contrast requirements in thumbnail color extraction ([ThibG](https://github.com/tootsuite/mastodon/pull/14464))
|
||||
- Fix audio/video player not using `CDN_HOST` on public pages ([ThibG](https://github.com/tootsuite/mastodon/pull/14486))
|
||||
- Fix private boost icon not being used on public pages ([OmmyZhang](https://github.com/tootsuite/mastodon/pull/14471))
|
||||
- Fix audio player on Safari in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/14485), [ThibG](https://github.com/tootsuite/mastodon/pull/14465))
|
||||
- Fix dereferencing remote statuses not using the correct account for signature when receiving a targeted inbox delivery ([ThibG](https://github.com/tootsuite/mastodon/pull/14656))
|
||||
- Fix nil error in `tootctl media remove` ([noellabo](https://github.com/tootsuite/mastodon/pull/14657))
|
||||
- Fix videos with near-60 fps being rejected ([Gargron](https://github.com/tootsuite/mastodon/pull/14684))
|
||||
- Fix reported statuses not being included in warning e-mail ([Gargron](https://github.com/tootsuite/mastodon/pull/14778))
|
||||
- Fix `Reject` activities of `Follow` objects not correctly destroying a follow relationship ([ThibG](https://github.com/tootsuite/mastodon/pull/14479))
|
||||
- Fix inefficiencies in fan-out-on-write service ([Gargron](https://github.com/tootsuite/mastodon/pull/14682), [noellabo](https://github.com/tootsuite/mastodon/pull/14709))
|
||||
- Fix timeout errors when trying to webfinger some IPv6 configurations ([Gargron](https://github.com/tootsuite/mastodon/pull/14919))
|
||||
- Fix files served as `application/octet-stream` being rejected without attempting mime type detection ([ThibG](https://github.com/tootsuite/mastodon/pull/14452))
|
||||
|
||||
## [3.2.0] - 2020-07-27
|
||||
### Added
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ FROM ubuntu:20.04 as build-dep
|
|||
SHELL ["bash", "-c"]
|
||||
|
||||
# Install Node v12 (LTS)
|
||||
ENV NODE_VER="12.16.3"
|
||||
ENV NODE_VER="12.20.0"
|
||||
RUN ARCH= && \
|
||||
dpkgArch="$(dpkg --print-architecture)" && \
|
||||
case "${dpkgArch##*-}" in \
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -44,6 +44,7 @@ gem 'net-ldap', '~> 0.16'
|
|||
gem 'omniauth-cas', '~> 2.0'
|
||||
gem 'omniauth-saml', '~> 1.10'
|
||||
gem 'omniauth', '~> 1.9'
|
||||
gem 'omniauth-rails_csrf_protection', '~> 0.1'
|
||||
|
||||
gem 'color_diff', '~> 0.1'
|
||||
gem 'discard', '~> 1.2'
|
||||
|
@ -81,6 +82,7 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
|||
gem 'rqrcode', '~> 1.1'
|
||||
gem 'ruby-progressbar', '~> 1.10'
|
||||
gem 'sanitize', '~> 5.2'
|
||||
gem 'scenic', '~> 1.5'
|
||||
gem 'sidekiq', '~> 6.1'
|
||||
gem 'sidekiq-scheduler', '~> 3.0'
|
||||
gem 'sidekiq-unique-jobs', '~> 6.0'
|
||||
|
|
|
@ -375,6 +375,9 @@ GEM
|
|||
addressable (~> 2.3)
|
||||
nokogiri (~> 1.5)
|
||||
omniauth (~> 1.2)
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
omniauth-saml (1.10.3)
|
||||
omniauth (~> 1.3, >= 1.3.2)
|
||||
ruby-saml (~> 1.9)
|
||||
|
@ -558,6 +561,9 @@ GEM
|
|||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.8.0)
|
||||
nokogumbo (~> 2.0)
|
||||
scenic (1.5.4)
|
||||
activerecord (>= 4.0.0)
|
||||
railties (>= 4.0.0)
|
||||
securecompare (1.0.0)
|
||||
semantic_range (2.3.0)
|
||||
sidekiq (6.1.2)
|
||||
|
@ -741,6 +747,7 @@ DEPENDENCIES
|
|||
oj (~> 3.10)
|
||||
omniauth (~> 1.9)
|
||||
omniauth-cas (~> 2.0)
|
||||
omniauth-rails_csrf_protection (~> 0.1)
|
||||
omniauth-saml (~> 1.10)
|
||||
ox (~> 2.13)
|
||||
paperclip (~> 6.0)
|
||||
|
@ -778,6 +785,7 @@ DEPENDENCIES
|
|||
rubocop-rails (~> 2.8)
|
||||
ruby-progressbar (~> 1.10)
|
||||
sanitize (~> 5.2)
|
||||
scenic (~> 1.5)
|
||||
sidekiq (~> 6.1)
|
||||
sidekiq-bulk (~> 0.2.0)
|
||||
sidekiq-scheduler (~> 3.0)
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AboutController < ApplicationController
|
||||
include RegistrationSpamConcern
|
||||
|
||||
layout 'public'
|
||||
|
||||
before_action :require_open_federation!, only: [:show, :more]
|
||||
before_action :set_body_classes, only: :show
|
||||
before_action :set_instance_presenter
|
||||
before_action :set_expires_in, only: [:show, :more, :terms]
|
||||
before_action :set_expires_in, only: [:more, :terms]
|
||||
before_action :set_registration_form_time, only: :show
|
||||
|
||||
skip_before_action :require_functional!, only: [:more, :terms]
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class AccountsController < ApplicationController
|
|||
end
|
||||
|
||||
def account_media_status_ids
|
||||
@account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
||||
@account.media_attachments.attached.reorder(nil).select(:status_id).group(:status_id)
|
||||
end
|
||||
|
||||
def no_replies_scope
|
||||
|
|
|
@ -29,6 +29,7 @@ module Admin
|
|||
@domain_block = existing_domain_block
|
||||
@domain_block.update(resource_params)
|
||||
end
|
||||
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
log_action :create, @domain_block
|
||||
|
@ -40,7 +41,7 @@ module Admin
|
|||
end
|
||||
|
||||
def update
|
||||
authorize :domain_block, :create?
|
||||
authorize :domain_block, :update?
|
||||
|
||||
@domain_block.update(update_params)
|
||||
|
||||
|
@ -48,7 +49,7 @@ module Admin
|
|||
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id, severity_changed)
|
||||
log_action :create, @domain_block
|
||||
log_action :update, @domain_block
|
||||
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
||||
else
|
||||
render :edit
|
||||
|
@ -73,11 +74,11 @@ module Admin
|
|||
end
|
||||
|
||||
def update_params
|
||||
params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment)
|
||||
params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment)
|
||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,65 +2,31 @@
|
|||
|
||||
module Admin
|
||||
class InstancesController < BaseController
|
||||
before_action :set_domain_block, only: :show
|
||||
before_action :set_domain_allow, only: :show
|
||||
before_action :set_instances, only: :index
|
||||
before_action :set_instance, only: :show
|
||||
|
||||
def index
|
||||
authorize :instance, :index?
|
||||
|
||||
@instances = ordered_instances
|
||||
end
|
||||
|
||||
def show
|
||||
authorize :instance, :show?
|
||||
|
||||
@following_count = Follow.where(account: Account.where(domain: params[:id])).count
|
||||
@followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
|
||||
@reports_count = Report.where(target_account: Account.where(domain: params[:id])).count
|
||||
@blocks_count = Block.where(target_account: Account.where(domain: params[:id])).count
|
||||
@available = DeliveryFailureTracker.available?(params[:id])
|
||||
@media_storage = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
|
||||
@private_comment = @domain_block&.private_comment
|
||||
@public_comment = @domain_block&.public_comment
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_domain_block
|
||||
@domain_block = DomainBlock.rule_for(params[:id])
|
||||
end
|
||||
|
||||
def set_domain_allow
|
||||
@domain_allow = DomainAllow.rule_for(params[:id])
|
||||
end
|
||||
|
||||
def set_instance
|
||||
resource = Account.by_domain_accounts.find_by(domain: params[:id])
|
||||
resource ||= @domain_block
|
||||
resource ||= @domain_allow
|
||||
@instance = Instance.find(params[:id])
|
||||
end
|
||||
|
||||
if resource
|
||||
@instance = Instance.new(resource)
|
||||
else
|
||||
not_found
|
||||
end
|
||||
def set_instances
|
||||
@instances = filtered_instances.page(params[:page])
|
||||
end
|
||||
|
||||
def filtered_instances
|
||||
InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
|
||||
end
|
||||
|
||||
def paginated_instances
|
||||
filtered_instances.page(params[:page])
|
||||
end
|
||||
|
||||
helper_method :paginated_instances
|
||||
|
||||
def ordered_instances
|
||||
paginated_instances.map { |resource| Instance.new(resource) }
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.slice(*InstanceFilter::KEYS).permit(*InstanceFilter::KEYS)
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ module Admin
|
|||
@statuses = @account.statuses.where(visibility: [:public, :unlisted])
|
||||
|
||||
if params[:media]
|
||||
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
||||
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).group(:status_id)
|
||||
@statuses.merge!(Status.where(id: account_media_status_ids))
|
||||
end
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class Api::BaseController < ApplicationController
|
|||
render json: { error: 'This action is not allowed' }, status: 403
|
||||
end
|
||||
|
||||
rescue_from Mastodon::RaceConditionError do
|
||||
rescue_from Mastodon::RaceConditionError, Seahorse::Client::NetworkingError, Stoplight::Error::RedLight do
|
||||
render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ class Api::V1::Accounts::FeaturedTagsController < Api::BaseController
|
|||
respond_to :json
|
||||
|
||||
def index
|
||||
render json: @featured_tags, each_serializer: REST::AccountFeaturedTagSerializer
|
||||
render json: @featured_tags, each_serializer: REST::FeaturedTagSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -17,6 +17,6 @@ class Api::V1::Accounts::FeaturedTagsController < Api::BaseController
|
|||
end
|
||||
|
||||
def set_featured_tags
|
||||
@featured_tags = @account.suspended? ? @account.featured_tags : []
|
||||
@featured_tags = @account.suspended? ? [] : @account.featured_tags
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ class Api::V1::Instances::PeersController < Api::BaseController
|
|||
|
||||
def index
|
||||
expires_in 1.day, public: true
|
||||
render_with_cache(expires_in: 1.day) { Account.remote.domains }
|
||||
render_with_cache(expires_in: 1.day) { Instance.where.not(domain: DomainBlock.select(:domain)).pluck(:domain) }
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -28,7 +28,7 @@ class ApplicationController < ActionController::Base
|
|||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
||||
rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
|
||||
rescue_from Mastodon::RaceConditionError, with: :service_unavailable
|
||||
rescue_from Mastodon::RaceConditionError, Seahorse::Client::NetworkingError, Stoplight::Error::RedLight, with: :service_unavailable
|
||||
rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
|
||||
|
||||
before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
include Devise::Controllers::Rememberable
|
||||
include RegistrationSpamConcern
|
||||
|
||||
layout :determine_layout
|
||||
|
||||
|
@ -13,6 +14,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
||||
before_action :require_not_suspended!, only: [:update]
|
||||
before_action :set_cache_headers, only: [:edit, :update]
|
||||
before_action :set_registration_form_time, only: :new
|
||||
|
||||
skip_before_action :require_functional!, only: [:edit, :update]
|
||||
|
||||
|
@ -45,16 +47,17 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
def build_resource(hash = nil)
|
||||
super(hash)
|
||||
|
||||
resource.locale = I18n.locale
|
||||
resource.invite_code = params[:invite_code] if resource.invite_code.blank?
|
||||
resource.sign_up_ip = request.remote_ip
|
||||
resource.locale = I18n.locale
|
||||
resource.invite_code = params[:invite_code] if resource.invite_code.blank?
|
||||
resource.registration_form_time = session[:registration_form_time]
|
||||
resource.sign_up_ip = request.remote_ip
|
||||
|
||||
resource.build_account if resource.account.nil?
|
||||
end
|
||||
|
||||
def configure_sign_up_params
|
||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
||||
u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code, :agreement)
|
||||
u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code, :agreement, :website, :confirm_password)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module RegistrationSpamConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def set_registration_form_time
|
||||
session[:registration_form_time] = Time.now.utc
|
||||
end
|
||||
end
|
|
@ -7,6 +7,13 @@ module ApplicationHelper
|
|||
follow
|
||||
).freeze
|
||||
|
||||
RTL_LOCALES = %i(
|
||||
ar
|
||||
fa
|
||||
he
|
||||
ku
|
||||
).freeze
|
||||
|
||||
def active_nav_class(*paths)
|
||||
paths.any? { |path| current_page?(path) } ? 'active' : ''
|
||||
end
|
||||
|
@ -44,7 +51,7 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def locale_direction
|
||||
if [:ar, :fa, :he].include?(I18n.locale)
|
||||
if RTL_LOCALES.include?(I18n.locale)
|
||||
'rtl'
|
||||
else
|
||||
'ltr'
|
||||
|
|
|
@ -92,22 +92,6 @@ module StatusesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def rtl_status?(status)
|
||||
status.local? ? rtl?(status.text) : rtl?(strip_tags(status.text))
|
||||
end
|
||||
|
||||
def rtl?(text)
|
||||
text = simplified_text(text)
|
||||
rtl_words = text.scan(/[\p{Hebrew}\p{Arabic}\p{Syriac}\p{Thaana}\p{Nko}]+/m)
|
||||
|
||||
if rtl_words.present?
|
||||
total_size = text.size.to_f
|
||||
rtl_size(rtl_words) / total_size > 0.3
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def fa_visibility_icon(status)
|
||||
case status.visibility
|
||||
when 'public'
|
||||
|
@ -143,10 +127,6 @@ module StatusesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def rtl_size(words)
|
||||
words.reduce(0) { |acc, elem| acc + elem.size }.to_f
|
||||
end
|
||||
|
||||
def embedded_view?
|
||||
params[:controller] == EMBEDDED_CONTROLLER && params[:action] == EMBEDDED_ACTION
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import api from '../api';
|
||||
import { debounce } from 'lodash';
|
||||
import compareId from '../compare_id';
|
||||
import { showAlertForError } from './alerts';
|
||||
|
||||
export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST';
|
||||
export const MARKERS_FETCH_SUCCESS = 'MARKERS_FETCH_SUCCESS';
|
||||
|
@ -29,15 +28,19 @@ export const synchronouslySubmitMarkers = () => (dispatch, getState) => {
|
|||
},
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
|
||||
return;
|
||||
} else if (navigator && navigator.sendBeacon) {
|
||||
// Failing that, we can use sendBeacon, but we have to encode the data as
|
||||
// FormData for DoorKeeper to recognize the token.
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append('bearer_token', accessToken);
|
||||
|
||||
for (const [id, value] of Object.entries(params)) {
|
||||
formData.append(`${id}[last_read_id]`, value.last_read_id);
|
||||
}
|
||||
|
||||
if (navigator.sendBeacon('/api/v1/markers', formData)) {
|
||||
return;
|
||||
}
|
||||
|
@ -85,11 +88,9 @@ const debouncedSubmitMarkers = debounce((dispatch, getState) => {
|
|||
return;
|
||||
}
|
||||
|
||||
api().post('/api/v1/markers', params).then(() => {
|
||||
api(getState).post('/api/v1/markers', params).then(() => {
|
||||
dispatch(submitMarkersSuccess(params));
|
||||
}).catch(error => {
|
||||
dispatch(showAlertForError(error));
|
||||
});
|
||||
}).catch(() => {});
|
||||
}, 300000, { leading: true, trailing: true });
|
||||
|
||||
export function submitMarkersSuccess({ home, notifications }) {
|
||||
|
@ -102,9 +103,11 @@ export function submitMarkersSuccess({ home, notifications }) {
|
|||
|
||||
export function submitMarkers(params = {}) {
|
||||
const result = (dispatch, getState) => debouncedSubmitMarkers(dispatch, getState);
|
||||
|
||||
if (params.immediate === true) {
|
||||
debouncedSubmitMarkers.flush();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
|
@ -37,9 +37,8 @@ export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
|
|||
|
||||
export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
|
||||
|
||||
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
||||
export const NOTIFICATIONS_DISMISS_BROWSER_PERMISSION = 'NOTIFICATIONS_DISMISS_BROWSER_PERMISSION';
|
||||
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
||||
|
||||
defineMessages({
|
||||
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
||||
|
@ -284,7 +283,3 @@ export function setBrowserPermission (value) {
|
|||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export const dismissBrowserPermission = () => ({
|
||||
type: NOTIFICATIONS_DISMISS_BROWSER_PERMISSION,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
const DIGIT_CHARACTERS = [
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'A',
|
||||
'B',
|
||||
'C',
|
||||
'D',
|
||||
'E',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'I',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
'M',
|
||||
'N',
|
||||
'O',
|
||||
'P',
|
||||
'Q',
|
||||
'R',
|
||||
'S',
|
||||
'T',
|
||||
'U',
|
||||
'V',
|
||||
'W',
|
||||
'X',
|
||||
'Y',
|
||||
'Z',
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
'd',
|
||||
'e',
|
||||
'f',
|
||||
'g',
|
||||
'h',
|
||||
'i',
|
||||
'j',
|
||||
'k',
|
||||
'l',
|
||||
'm',
|
||||
'n',
|
||||
'o',
|
||||
'p',
|
||||
'q',
|
||||
'r',
|
||||
's',
|
||||
't',
|
||||
'u',
|
||||
'v',
|
||||
'w',
|
||||
'x',
|
||||
'y',
|
||||
'z',
|
||||
'#',
|
||||
'$',
|
||||
'%',
|
||||
'*',
|
||||
'+',
|
||||
',',
|
||||
'-',
|
||||
'.',
|
||||
':',
|
||||
';',
|
||||
'=',
|
||||
'?',
|
||||
'@',
|
||||
'[',
|
||||
']',
|
||||
'^',
|
||||
'_',
|
||||
'{',
|
||||
'|',
|
||||
'}',
|
||||
'~',
|
||||
];
|
||||
|
||||
export const decode83 = (str) => {
|
||||
let value = 0;
|
||||
let c, digit;
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
c = str[i];
|
||||
digit = DIGIT_CHARACTERS.indexOf(c);
|
||||
value = value * 83 + digit;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
export const intToRGB = int => ({
|
||||
r: Math.max(0, (int >> 16)),
|
||||
g: Math.max(0, (int >> 8) & 255),
|
||||
b: Math.max(0, (int & 255)),
|
||||
});
|
||||
|
||||
export const getAverageFromBlurhash = blurhash => {
|
||||
if (!blurhash) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return intToRGB(decode83(blurhash.slice(2, 6)));
|
||||
};
|
|
@ -4,7 +4,6 @@ import AutosuggestEmoji from './autosuggest_emoji';
|
|||
import AutosuggestHashtag from './autosuggest_hashtag';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isRtl } from '../rtl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import classNames from 'classnames';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
|
@ -189,11 +188,6 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
|||
render () {
|
||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength } = this.props;
|
||||
const { suggestionsHidden } = this.state;
|
||||
const style = { direction: 'ltr' };
|
||||
|
||||
if (isRtl(value)) {
|
||||
style.direction = 'rtl';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='autosuggest-input'>
|
||||
|
@ -212,7 +206,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
|||
onKeyUp={onKeyUp}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
style={style}
|
||||
dir='auto'
|
||||
aria-autocomplete='list'
|
||||
id={id}
|
||||
className={className}
|
||||
|
|
|
@ -4,7 +4,6 @@ import AutosuggestEmoji from './autosuggest_emoji';
|
|||
import AutosuggestHashtag from './autosuggest_hashtag';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isRtl } from '../rtl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Textarea from 'react-textarea-autosize';
|
||||
import classNames from 'classnames';
|
||||
|
@ -204,11 +203,6 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
render() {
|
||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, children } = this.props;
|
||||
const { suggestionsHidden } = this.state;
|
||||
const style = { direction: 'ltr' };
|
||||
|
||||
if (isRtl(value)) {
|
||||
style.direction = 'rtl';
|
||||
}
|
||||
|
||||
return [
|
||||
<div
|
||||
|
@ -232,7 +226,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
|||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
onPaste={this.onPaste}
|
||||
style={style}
|
||||
dir='auto'
|
||||
aria-autocomplete='list'
|
||||
/>
|
||||
</label >
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import 'wicg-inert';
|
||||
import { multiply } from 'color-blend';
|
||||
|
||||
export default class ModalRoot extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.node,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
backgroundColor: PropTypes.shape({
|
||||
r: PropTypes.number,
|
||||
g: PropTypes.number,
|
||||
b: PropTypes.number,
|
||||
}),
|
||||
};
|
||||
|
||||
activeElement = this.props.children ? document.activeElement : null;
|
||||
|
@ -62,9 +68,7 @@ export default class ModalRoot extends React.PureComponent {
|
|||
Promise.resolve().then(() => {
|
||||
this.activeElement.focus({ preventScroll: true });
|
||||
this.activeElement = null;
|
||||
}).catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
}).catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,10 +95,16 @@ export default class ModalRoot extends React.PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
let backgroundColor = null;
|
||||
|
||||
if (this.props.backgroundColor) {
|
||||
backgroundColor = multiply({ ...this.props.backgroundColor, a: 1 }, { r: 0, g: 0, b: 0, a: 0.7 });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='modal-root' ref={this.setRef}>
|
||||
<div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
|
||||
<div role='presentation' className='modal-root__overlay' onClick={onClose} />
|
||||
<div role='presentation' className='modal-root__overlay' onClick={onClose} style={{ backgroundColor: backgroundColor ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, 0.7)` : null }} />
|
||||
<div role='dialog' className='modal-root__container'>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -97,7 +97,7 @@ class Status extends ImmutablePureComponent {
|
|||
cachedMediaWidth: PropTypes.number,
|
||||
scrollKey: PropTypes.string,
|
||||
deployPictureInPicture: PropTypes.func,
|
||||
pictureInPicture: PropTypes.shape({
|
||||
pictureInPicture: ImmutablePropTypes.contains({
|
||||
inUse: PropTypes.bool,
|
||||
available: PropTypes.bool,
|
||||
}),
|
||||
|
@ -192,8 +192,13 @@ class Status extends ImmutablePureComponent {
|
|||
return <div className='audio-player' style={{ height: '110px' }} />;
|
||||
}
|
||||
|
||||
handleOpenVideo = (media, options) => {
|
||||
this.props.onOpenVideo(media, options);
|
||||
handleOpenVideo = (options) => {
|
||||