Progress
@ -1,327 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<defs >
|
||||
<font id="Montserrat" horiz-adv-x="672" ><font-face
|
||||
font-family="Montserrat ExtraBold"
|
||||
units-per-em="1000"
|
||||
panose-1="0 0 9 0 0 0 0 0 0 0"
|
||||
ascent="968"
|
||||
descent="-251"
|
||||
alphabetic="0" />
|
||||
<glyph unicode=" " glyph-name="space" horiz-adv-x="291" />
|
||||
<glyph unicode="!" glyph-name="exclam" horiz-adv-x="301" d="M38 700H264L226 255H75L38 700ZM101 -9T69 21T37 96Q37 141 69 170T151 199Q201 199 232 170T264 96Q264 52 232 22T151 -9Q101 -9 69 21Z" />
|
||||
<glyph unicode=""" glyph-name="quotedbl" horiz-adv-x="462" d="M41 700H201L188 408H53L41 700ZM261 700H421L408 408H273L261 700Z" />
|
||||
<glyph unicode="#" glyph-name="numbersign" horiz-adv-x="730" d="M571 422L554 278H679V149H538L519 0H383L402 149H279L260 0H124L143 149H17V278H159L176 422H50V551H192L211 700H347L328 551H451L470 700H606L587 551H713V422H571ZM435 422H312L295 278H418L435
|
||||
422Z" />
|
||||
<glyph unicode="$" glyph-name="dollar" horiz-adv-x="647" d="M626 129T567 69T394 -9V-120H274V-13Q199 -8 132 12T21 63L86 209Q133 178 195 159T317 140Q431 140 431 197Q431 227 399 241T294 272Q215 289 162 308T71 371T33 487Q33 573 95 634T274 710V820H394V712Q451
|
||||
707 503 692T597 653L536 506Q436 560 342 560Q283 560 256 543T229 497Q229 469 261 455T364 426Q444 409 496 390T587 328T626 212Q626 129 567 69Z" />
|
||||
<glyph unicode="%" glyph-name="percent" horiz-adv-x="897" d="M122 321T72 373T22 515Q22 574 45 618T108 685T201 709Q281 709 331 657T381 515Q381 425 331 373T201 321Q122 321 72 373ZM615 700H759L281 0H137L615 700ZM228 416T244 440T260 515Q260 566
|
||||
244 590T201 614Q175 614 159 590T142 515Q142 465 158 441T201 416Q228 416 244 440ZM615 -9T566 43T516 185Q516 274 566 326T695 379Q775 379 825 327T875 185Q875 95 825 43T695 -9Q615 -9 566 43ZM722 86T738 110T754 185Q754 236 738 260T695 284Q668 284
|
||||
652 260T636 185Q636 134 652 110T695 86Q722 86 738 110Z" />
|
||||
<glyph unicode="&" glyph-name="ampersand" horiz-adv-x="752" d="M624 -12L545 58Q496 23 436 5T310 -14Q231 -14 167 11T67 82T31 183Q31 249 66 298T177 389Q110 457 110 530Q110 583 139 624T221 687T345 710Q442 710 501 665T561 542Q561 488 530 446T431
|
||||
367L533 276Q553 320 564 376L717 330Q697 240 652 171L726 105L624 -12ZM316 585T300 571T283 533Q283 516 292 501T328 460Q368 481 384 499T401 538Q401 560 387 572T345 585Q316 585 300 571ZM382 131T431 160L280 294Q247 274 232 253T217 204Q217 172 246
|
||||
152T324 131Q382 131 431 160Z" />
|
||||
<glyph unicode="'" glyph-name="quotesingle" horiz-adv-x="242" d="M41 700H201L188 408H53L41 700Z" />
|
||||
<glyph unicode="(" glyph-name="parenleft" horiz-adv-x="369" d="M127 -104T94 16T60 274Q60 411 93 531T189 742H371Q306 627 276 514T246 274Q246 148 276 35T371 -194H189Q127 -104 94 16Z" />
|
||||
<glyph unicode=")" glyph-name="parenright" horiz-adv-x="369" d="M-2 -194Q63 -79 93 34T123 274Q123 400 93 513T-2 742H180Q242 652 275 532T309 274Q309 137 276 17T180 -194H-2Z" />
|
||||
<glyph unicode="*" glyph-name="asterisk" horiz-adv-x="453" d="M341 538L443 483L385 387L280 450L283 335H169L172 450L67 387L10 483L112 538L10 594L67 690L172 626L169 742H283L280 626L385 690L443 594L341 538Z" />
|
||||
<glyph unicode="+" glyph-name="plus" horiz-adv-x="609" d="M551 277H382V112H228V277H58V423H228V588H382V423H551V277Z" />
|
||||
<glyph unicode="," glyph-name="comma" horiz-adv-x="283" d="M191 216T223 185T255 104Q255 81 249 58T222 -11L159 -157H40L87 6Q59 19 44 44T28 104Q28 154 60 185T142 216Q191 216 223 185Z" />
|
||||
<glyph unicode="-" glyph-name="hyphen" horiz-adv-x="388" d="M48 358H340V212H48V358Z" />
|
||||
<glyph unicode="." glyph-name="period" horiz-adv-x="283" d="M93 -9T60 23T27 104Q27 154 59 185T141 216Q191 216 223 185T255 104Q255 55 223 23T141 -9Q93 -9 60 23Z" />
|
||||
<glyph unicode="/" glyph-name="slash" horiz-adv-x="415" d="M293 842H462L132 -100H-37L293 842Z" />
|
||||
<glyph unicode="0" glyph-name="zero" horiz-adv-x="685" d="M253 -14T183 29T74 154T34 350Q34 463 73 545T183 671T343 714Q432 714 502 671T611 546T651 350Q651 237 612 155T502 29T343 -14Q253 -14 183 29ZM393 148T422 196T452 350Q452 455 423 503T343
|
||||
552Q292 552 263 504T233 350Q233 245 262 197T343 148Q393 148 422 196Z" />
|
||||
<glyph unicode="1" glyph-name="one" horiz-adv-x="405" d="M334 700V0H136V547H6V700H334Z" />
|
||||
<glyph unicode="2" glyph-name="two" horiz-adv-x="599" d="M575 157V0H30V124L292 369Q330 405 343 430T356 482Q356 516 333 535T266 554Q227 554 195 537T141 486L-6 568Q35 636 109 675T284 714Q364 714 425 688T521 614T556 501Q556 444 532 394T437 279L305
|
||||
157H575Z" />
|
||||
<glyph unicode="3" glyph-name="three" horiz-adv-x="603" d="M480 402T526 349T573 219Q573 157 540 104T438 19T268 -14Q194 -14 122 4T-4 55L68 204Q109 176 160 161T262 146Q313 146 343 165T373 219Q373 287 266 287H183V412L308 547H32V700H538V576L393
|
||||
420Q480 402 526 349Z" />
|
||||
<glyph unicode="4" glyph-name="four" horiz-adv-x="700" d="M694 134H590V0H397V134H27V263L341 700H546L261 291H403V410H590V291H694V134Z" />
|
||||
<glyph unicode="5" glyph-name="five" horiz-adv-x="607" d="M443 445T513 385T584 225Q584 160 551 106T449 19T279 -14Q205 -14 133 4T8 55L79 204Q121 176 171 161T273 146Q324 146 354 165T385 220Q385 255 355 273T249 291H59L94 700H540V547H258L249 445H296Q443
|
||||
445 513 385Z" />
|
||||
<glyph unicode="6" glyph-name="six" horiz-adv-x="649" d="M458 446T513 419T600 341T633 225Q633 154 597 100T498 16T358 -14Q208 -14 121 75T34 331Q34 451 80 537T211 669T406 714Q466 714 520 701T612 663L540 521Q489 557 411 557Q335 557 288 515T234
|
||||
394Q294 446 392 446Q458 446 513 419ZM388 127T414 151T441 216Q441 256 415 280T345 304Q302 304 275 280T248 215Q248 176 274 152T346 127Q388 127 414 151Z" />
|
||||
<glyph unicode="7" glyph-name="seven" horiz-adv-x="632" d="M603 700V576L356 0H140L376 543H192V435H23V700H603Z" />
|
||||
<glyph unicode="8" glyph-name="eight" horiz-adv-x="669" d="M586 341T612 300T638 206Q638 140 600 90T493 13T334 -14Q244 -14 175 13T68 90T30 206Q30 259 56 300T130 369Q94 394 75 430T55 510Q55 571 90 617T188 689T334 714Q416 714 479 689T578 618T613
|
||||
510Q613 466 594 430T538 369Q586 341 612 300ZM297 575T274 556T251 501Q251 467 273 448T334 428Q372 428 395 447T418 501Q418 536 395 555T334 575Q297 575 274 556ZM382 125T410 148T439 212Q439 252 411 275T334 299Q286 299 258 276T229 212Q229 172 257
|
||||
149T334 125Q382 125 410 148Z" />
|
||||
<glyph unicode="9" glyph-name="nine" horiz-adv-x="649" d="M441 714T528 625T615 369Q615 249 569 163T438 31T242 -14Q183 -14 129 -1T37 37L109 179Q160 143 238 143Q313 143 359 184T414 305Q354 254 257 254Q191 254 136 281T49 359T16 475Q16 546 52 600T151
|
||||
684T290 714Q441 714 528 625ZM347 396T374 420T401 485Q401 524 375 548T303 573Q261 573 235 549T208 484Q208 444 234 420T304 396Q347 396 374 420Z" />
|
||||
<glyph unicode=":" glyph-name="colon" horiz-adv-x="283" d="M93 326T60 358T27 439Q27 489 59 520T141 551Q191 551 223 520T255 439Q255 390 223 358T141 326Q93 326 60 358ZM93 -9T60 23T27 104Q27 154 59 185T141 216Q191 216 223 185T255 104Q255 55 223
|
||||
23T141 -9Q93 -9 60 23Z" />
|
||||
<glyph unicode=";" glyph-name="semicolon" horiz-adv-x="283" d="M93 326T60 358T27 439Q27 489 59 520T141 551Q191 551 223 520T255 439Q255 390 223 358T141 326Q93 326 60 358ZM191 216T223 185T255 104Q255 81 249 58T222 -11L159 -157H40L87 6Q59 19 44
|
||||
44T28 104Q28 154 60 185T142 216Q191 216 223 185Z" />
|
||||
<glyph unicode="<" glyph-name="less" horiz-adv-x="609" d="M551 463L232 350L551 237V91L58 273V427L551 609V463Z" />
|
||||
<glyph unicode="=" glyph-name="equal" horiz-adv-x="609" d="M58 549H551V404H58V549ZM58 296H551V151H58V296Z" />
|
||||
<glyph unicode=">" glyph-name="greater" horiz-adv-x="609" d="M551 427V273L58 91V237L377 350L58 463V609L551 427Z" />
|
||||
<glyph unicode="?" glyph-name="question" horiz-adv-x="597" d="M212 305T234 337T298 409Q327 436 341 454T355 494Q355 523 331 540T267 558Q227 558 195 539T142 486L-7 566Q34 636 109 675T290 714Q409 714 481 665T554 526Q554 485 540 454T507 401T456
|
||||
352Q422 323 406 303T390 255H212Q212 305 234 337ZM252 -9T220 21T188 96Q188 141 219 170T301 199Q351 199 383 170T415 96Q415 52 383 22T301 -9Q252 -9 220 21Z" />
|
||||
<glyph unicode="@" glyph-name="at" horiz-adv-x="1036" d="M664 712T772 655T941 499T1002 278Q1002 188 974 124T896 26T782 -8Q729 -8 691 14T635 79Q586 -8 473 -8Q414 -8 363 23T282 112T251 243Q251 317 281 374T362 462T473 493Q561 493 612 436V485H775V180Q775
|
||||
148 787 134T819 120Q882 120 882 275Q882 370 838 444T712 559T525 601Q420 601 339 556T212 432T167 253Q167 152 211 72T335 -52T521 -97Q628 -97 720 -53L757 -160Q712 -182 649 -195T521 -208Q376 -208 266 -148T95 17T34 253Q34 383 95 487T267 652T525 712Q664
|
||||
712 772 655ZM560 128T587 158T615 243Q615 297 588 327T516 357Q472 357 445 327T418 243Q418 189 445 159T516 128Q560 128 587 158Z" />
|
||||
<glyph unicode="A" glyph-name="A" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481Z" />
|
||||
<glyph unicode="B" glyph-name="B" horiz-adv-x="769" d="M668 344T702 300T736 192Q736 100 662 50T448 0H70V700H428Q562 700 632 651T702 517Q702 467 678 428T608 365Q668 344 702 300ZM266 557V422H402Q502 422 502 490Q502 557 402 557H266ZM536 143T536
|
||||
214Q536 285 432 285H266V143H432Q536 143 536 214Z" />
|
||||
<glyph unicode="C" glyph-name="C" horiz-adv-x="738" d="M309 -14T222 32T84 162T34 350Q34 455 84 538T221 667T419 714Q515 714 592 680T720 582L594 468Q526 550 429 550Q372 550 328 525T259 455T234 350Q234 291 258 246T327 175T429 150Q526 150 594 232L720
|
||||
118Q669 54 592 20T419 -14Q309 -14 222 32Z" />
|
||||
<glyph unicode="D" glyph-name="D" horiz-adv-x="826" d="M70 700H401Q516 700 605 657T743 535T792 350Q792 244 743 165T605 43T401 0H70V700ZM393 158Q483 158 537 209T592 350Q592 440 538 491T393 542H268V158H393Z" />
|
||||
<glyph unicode="E" glyph-name="E" d="M632 153V0H70V700H619V547H266V429H577V281H266V153H632Z" />
|
||||
<glyph unicode="F" glyph-name="F" horiz-adv-x="642" d="M268 547V393H577V240H268V0H70V700H619V547H268Z" />
|
||||
<glyph unicode="G" glyph-name="G" horiz-adv-x="770" d="M539 365H714V75Q654 32 576 9T420 -14Q310 -14 222 32T84 162T34 350Q34 455 84 538T223 667T424 714Q522 714 600 681T730 586L604 472Q533 550 434 550Q344 550 289 496T234 350Q234 292 259 247T329
|
||||
176T432 150Q489 150 539 173V365Z" />
|
||||
<glyph unicode="H" glyph-name="H" horiz-adv-x="806" d="M736 700V0H538V273H268V0H70V700H268V437H538V700H736Z" />
|
||||
<glyph unicode="I" glyph-name="I" horiz-adv-x="339" d="M70 700H268V0H70V700Z" />
|
||||
<glyph unicode="J" glyph-name="J" horiz-adv-x="557" d="M146 -14T83 12T-20 89L88 217Q144 144 209 144Q252 144 274 170T297 246V547H55V700H493V258Q493 122 425 54T223 -14Q146 -14 83 12Z" />
|
||||
<glyph unicode="K" glyph-name="K" horiz-adv-x="752" d="M340 254L266 175V0H70V700H266V409L537 700H755L469 390L770 0H540L340 254Z" />
|
||||
<glyph unicode="L" glyph-name="L" horiz-adv-x="610" d="M70 700H268V157H602V0H70V700Z" />
|
||||
<glyph unicode="M" glyph-name="M" horiz-adv-x="954" d="M702 0L700 371L520 69H432L253 361V0H70V700H233L479 296L719 700H882L884 0H702Z" />
|
||||
<glyph unicode="N" glyph-name="N" horiz-adv-x="806" d="M736 700V0H573L264 373V0H70V700H233L542 327V700H736Z" />
|
||||
<glyph unicode="O" glyph-name="O" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612 409 587 454T519
|
||||
525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175Z" />
|
||||
<glyph unicode="P" glyph-name="P" horiz-adv-x="737" d="M485 700T555 669T663 579T701 441Q701 362 663 304T555 215T390 183H268V0H70V700H390Q485 700 555 669ZM439 339T470 365T501 441Q501 490 470 517T378 544H268V339H378Q439 339 470 365Z" />
|
||||
<glyph unicode="Q" glyph-name="Q" horiz-adv-x="846" d="M848 -81Q813 -124 763 -146T652 -169Q594 -169 547 -154T453 -105T346 -8Q255 7 184 57T74 183T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 232 748 142T574 12Q594
|
||||
-10 613 -19T656 -28Q715 -28 762 21L848 -81ZM234 291T259 246T327 175T423 150Q476 150 519 175T587 245T612 350Q612 409 587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246Z" />
|
||||
<glyph unicode="R" glyph-name="R" horiz-adv-x="740" d="M376 186H268V0H70V700H390Q485 700 555 669T663 579T701 441Q701 365 666 309T564 220L715 0H503L376 186ZM501 490T470 517T378 544H268V339H378Q439 339 470 365T501 441Q501 490 470 517Z" />
|
||||
<glyph unicode="S" glyph-name="S" horiz-adv-x="647" d="M231 -14T151 7T21 63L86 209Q133 178 195 159T317 140Q431 140 431 197Q431 227 399 241T294 272Q215 289 162 308T71 371T33 487Q33 551 68 602T172 684T343 714Q412 714 479 699T597 653L536 506Q436
|
||||
560 342 560Q283 560 256 543T229 497Q229 469 261 455T364 426Q444 409 496 390T587 328T626 212Q626 149 591 98T486 17T316 -14Q231 -14 151 7Z" />
|
||||
<glyph unicode="T" glyph-name="T" horiz-adv-x="635" d="M219 543H4V700H631V543H417V0H219V543Z" />
|
||||
<glyph unicode="U" glyph-name="U" horiz-adv-x="786" d="M237 -14T151 71T64 312V700H262V318Q262 150 395 150Q527 150 527 318V700H722V312Q722 156 636 71T393 -14Q237 -14 151 71Z" />
|
||||
<glyph unicode="V" glyph-name="V" horiz-adv-x="766" d="M780 700L480 0H285L-14 700H200L390 244L584 700H780Z" />
|
||||
<glyph unicode="W" glyph-name="W" horiz-adv-x="1184" d="M1168 700L941 0H729L595 426L455 0H243L16 700H220L361 253L509 700H691L832 249L979 700H1168Z" />
|
||||
<glyph unicode="X" glyph-name="X" horiz-adv-x="737" d="M512 0L367 217L224 0H-2L253 354L9 700H232L372 498L510 700H724L480 362L740 0H512Z" />
|
||||
<glyph unicode="Y" glyph-name="Y" horiz-adv-x="693" d="M445 251V0H247V254L-20 700H189L355 422L521 700H713L445 251Z" />
|
||||
<glyph unicode="Z" glyph-name="Z" horiz-adv-x="679" d="M662 157V0H35V124L388 543H44V700H647V576L294 157H662Z" />
|
||||
<glyph unicode="[" glyph-name="bracketleft" horiz-adv-x="389" d="M70 742H376V597H260V-49H376V-194H70V742Z" />
|
||||
<glyph unicode="\" glyph-name="backslash" horiz-adv-x="415" d="M283 -100L-47 842H122L452 -100H283Z" />
|
||||
<glyph unicode="]" glyph-name="bracketright" horiz-adv-x="389" d="M12 -194V-49H128V597H12V742H318V-194H12Z" />
|
||||
<glyph unicode="^" glyph-name="asciicircum" horiz-adv-x="610" d="M419 140L305 414L191 140H47L230 560H380L563 140H419Z" />
|
||||
<glyph unicode="_" glyph-name="underscore" horiz-adv-x="500" d="M0 0H500V-104H0V0Z" />
|
||||
<glyph unicode="`" glyph-name="grave" horiz-adv-x="600" d="M74 759H264L398 607H262L74 759Z" />
|
||||
<glyph unicode="a" glyph-name="a" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427 551 498 490ZM318
|
||||
111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127Z" />
|
||||
<glyph unicode="b" glyph-name="b" horiz-adv-x="695" d="M476 551T536 517T632 420T668 272Q668 188 633 124T537 26T402 -9Q295 -9 242 54V0H61V742H251V495Q306 551 402 551Q476 551 536 517ZM412 142T444 176T476 272Q476 332 444 366T362 400Q312 400 280
|
||||
366T248 272Q248 211 280 177T362 142Q412 142 444 176Z" />
|
||||
<glyph unicode="c" glyph-name="c" horiz-adv-x="603" d="M248 -9T177 27T67 127T27 272Q27 353 66 416T177 515T338 551Q430 551 497 512T592 402L445 327Q408 400 337 400Q286 400 253 366T219 272Q219 211 252 177T337 142Q408 142 445 215L592 140Q564 70
|
||||
497 31T338 -9Q248 -9 177 27Z" />
|
||||
<glyph unicode="d" glyph-name="d" horiz-adv-x="698" d="M637 742V0H456V54Q403 -9 297 -9Q223 -9 162 25T66 124T30 272Q30 356 65 419T162 517T297 551Q394 551 447 495V742H637ZM386 142T418 176T450 272Q450 332 419 366T337 400Q287 400 255 366T223 272Q223
|
||||
211 255 177T337 142Q386 142 418 176Z" />
|
||||
<glyph unicode="e" glyph-name="e" horiz-adv-x="642" d="M615 268T612 223H218Q230 181 264 159T351 136Q390 136 418 147T476 183L576 79Q497 -9 345 -9Q250 -9 178 27T67 127T27 272Q27 352 65 415T172 515T325 551Q406 551 472 518T576 421T615 270Q615 268
|
||||
612 223ZM282 416T253 391T215 323H437Q429 366 400 391T326 416Q282 416 253 391Z" />
|
||||
<glyph unicode="f" glyph-name="f" horiz-adv-x="406" d="M268 522H397V380H273V0H83V380H4V522H83V536Q83 635 142 693T309 751Q345 751 379 744T435 723L388 589Q360 605 331 605Q301 605 285 587T268 534V522Z" />
|
||||
<glyph unicode="g" glyph-name="g" horiz-adv-x="705" d="M644 542V99Q644 -52 562 -127T326 -203Q246 -203 176 -185T57 -132L126 1Q159 -26 209 -41T309 -57Q384 -57 419 -24T454 74V92Q399 28 293 28Q221 28 160 60T63 152T27 290Q27 367 63 426T160 518T293
|
||||
551Q409 551 463 476V542H644ZM389 179T422 210T456 290Q456 339 423 369T338 400Q286 400 253 370T219 290Q219 241 253 210T338 179Q389 179 422 210Z" />
|
||||
<glyph unicode="h" glyph-name="h" horiz-adv-x="696" d="M515 551T576 491T638 310V0H448V279Q448 390 359 390Q310 390 281 358T251 262V0H61V742H251V492Q282 521 324 536T414 551Q515 551 576 491Z" />
|
||||
<glyph unicode="i" glyph-name="i" horiz-adv-x="313" d="M61 542H251V0H61V542ZM104 602T72 631T40 703Q40 746 72 775T156 804Q208 804 240 777T272 706Q272 661 240 632T156 602Q104 602 72 631Z" />
|
||||
<glyph unicode="j" glyph-name="j" horiz-adv-x="320" d="M-45 -203T-94 -175L-46 -40Q-20 -56 13 -56Q39 -56 54 -38T69 15V542H259V14Q259 -86 201 -144T38 -203Q-45 -203 -94 -175ZM112 602T80 631T48 703Q48 746 80 775T164 804Q216 804 248 777T280 706Q280
|
||||
661 248 632T164 602Q112 602 80 631Z" />
|
||||
<glyph unicode="k" glyph-name="k" horiz-adv-x="686" d="M307 190L251 133V0H61V742H251V353L445 542H670L445 310L689 0H459L307 190Z" />
|
||||
<glyph unicode="l" glyph-name="l" horiz-adv-x="313" d="M61 742H251V0H61V742Z" />
|
||||
<glyph unicode="m" glyph-name="m" horiz-adv-x="1045" d="M867 551T926 491T986 310V0H796V279Q796 336 775 363T714 390Q671 390 645 360T619 269V0H429V279Q429 390 347 390Q303 390 277 360T251 269V0H61V542H242V485Q272 518 313 534T404 551Q461 551 506
|
||||
530T579 466Q611 507 660 529T767 551Q867 551 926 491Z" />
|
||||
<glyph unicode="n" glyph-name="n" horiz-adv-x="696" d="M515 551T576 491T638 310V0H448V279Q448 390 359 390Q310 390 281 358T251 262V0H61V542H242V483Q274 516 318 533T414 551Q515 551 576 491Z" />
|
||||
<glyph unicode="o" glyph-name="o" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333 400Q283
|
||||
400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176Z" />
|
||||
<glyph unicode="p" glyph-name="p" horiz-adv-x="695" d="M476 551T536 517T632 419T668 271Q668 187 633 124T537 26T402 -9Q307 -9 251 48V-194H61V542H242V488Q295 551 402 551Q476 551 536 517ZM412 142T444 176T476 271Q476 331 444 365T362 400Q312 400
|
||||
280 366T248 271Q248 211 280 177T362 142Q412 142 444 176Z" />
|
||||
<glyph unicode="q" glyph-name="q" horiz-adv-x="695" d="M634 542V-194H444V48Q389 -9 293 -9Q219 -9 159 25T63 123T27 271Q27 355 62 418T158 516T293 551Q400 551 453 488V542H634ZM383 142T415 176T447 271Q447 331 415 365T333 400Q283 400 251 366T219
|
||||
271Q219 211 251 177T333 142Q383 142 415 176Z" />
|
||||
<glyph unicode="r" glyph-name="r" horiz-adv-x="443" d="M271 514T317 532T424 551V380Q398 383 381 383Q320 383 286 350T251 249V0H61V542H242V477Q271 514 317 532Z" />
|
||||
<glyph unicode="s" glyph-name="s" horiz-adv-x="547" d="M190 -9T124 6T18 47L75 177Q112 154 163 141T264 127Q310 127 329 136T349 164Q349 182 326 189T251 204Q186 212 141 225T62 273T29 371Q29 423 60 463T150 527T293 551Q352 551 410 539T507 505L450
|
||||
376Q378 416 294 416Q249 416 228 406T207 378Q207 359 230 352T306 336Q373 326 417 313T493 266T526 169Q526 118 495 78T404 14T258 -9Q190 -9 124 6Z" />
|
||||
<glyph unicode="t" glyph-name="t" horiz-adv-x="447" d="M435 22Q411 7 377 -1T303 -9Q197 -9 140 43T83 198V380H4V522H83V663H273V522H397V380H273V200Q273 171 288 155T330 138Q363 138 388 155L435 22Z" />
|
||||
<glyph unicode="u" glyph-name="u" horiz-adv-x="692" d="M631 542V0H450V58Q420 25 378 8T289 -9Q184 -9 122 53T59 239V542H249V270Q249 209 272 181T339 153Q384 153 412 184T441 281V542H631Z" />
|
||||
<glyph unicode="v" glyph-name="v" horiz-adv-x="620" d="M632 542L408 0H212L-11 542H184L314 211L451 542H632Z" />
|
||||
<glyph unicode="w" glyph-name="w" horiz-adv-x="956" d="M959 542L766 0H582L480 295L374 0H190L-3 542H177L288 214L403 542H565L677 211L792 542H959Z" />
|
||||
<glyph unicode="x" glyph-name="x" horiz-adv-x="619" d="M405 0L308 142L204 0H-2L204 271L4 542H218L314 405L414 542H615L415 278L622 0H405Z" />
|
||||
<glyph unicode="y" glyph-name="y" horiz-adv-x="620" d="M632 542L398 -22Q357 -122 298 -162T154 -203Q111 -203 68 -190T-3 -154L63 -21Q79 -36 101 -44T147 -53Q174 -53 191 -42T221 -7L-11 542H184L317 211L451 542H632Z" />
|
||||
<glyph unicode="z" glyph-name="z" horiz-adv-x="556" d="M533 142V0H33V112L284 401H40V542H523V431L272 142H533Z" />
|
||||
<glyph unicode="{" glyph-name="braceleft" horiz-adv-x="414" d="M315 342T298 314T240 274Q280 263 297 235T315 151V23Q315 -12 333 -30T387 -49H401V-194H336Q232 -194 179 -144T125 1V156Q125 179 114 190T82 201H48V347H82Q102 347 113 358T125 392V547Q125
|
||||
641 178 691T336 742H401V597H387Q351 597 333 579T315 525V397Q315 342 298 314Z" />
|
||||
<glyph unicode="|" glyph-name="bar" horiz-adv-x="314" d="M70 742H244V-194H70V742Z" />
|
||||
<glyph unicode="}" glyph-name="braceright" horiz-adv-x="414" d="M365 347V201H332Q312 201 301 190T289 156V1Q289 -93 236 -143T78 -194H12V-49H27Q63 -49 81 -31T99 23V151Q99 206 116 234T174 274Q134 285 117 313T99 397V525Q99 560 81 578T27 597H12V742H78Q182
|
||||
742 235 692T289 547V392Q289 369 300 358T332 347H365Z" />
|
||||
<glyph unicode="~" glyph-name="asciitilde" horiz-adv-x="609" d="M369 243T343 256T282 293Q260 309 247 316T219 324Q194 324 179 306T162 254H45Q46 351 90 405T205 459Q241 459 267 446T328 409Q350 393 363 386T391 378Q416 378 430 397T447 449H564Q563
|
||||
351 519 297T404 243Q369 243 343 256Z" />
|
||||
<glyph unicode=" " glyph-name="uni00A0" horiz-adv-x="291" />
|
||||
<glyph unicode="¡" glyph-name="exclamdown" horiz-adv-x="301" d="M200 551T232 521T264 446Q264 402 233 373T151 343Q101 343 69 372T37 446Q37 490 69 520T151 551Q200 551 232 521ZM264 -154H38L75 287H226L264 -154Z" />
|
||||
<glyph unicode="¢" glyph-name="cent" horiz-adv-x="603" d="M408 142T445 215L592 140Q568 79 515 42T388 -6V-120H268V-3Q159 17 93 91T27 272Q27 342 57 399T141 494T268 545V662H388V548Q462 538 515 501T592 402L445 327Q408 400 337 400Q286 400 253
|
||||
366T219 272Q219 211 252 177T337 142Q408 142 445 215Z" />
|
||||
<glyph unicode="£" glyph-name="sterling" horiz-adv-x="681" d="M323 153H648V0H30V153H125V293H30V407H125V413Q125 556 214 635T466 714Q589 714 670 669L612 517Q556 550 476 550Q402 550 363 517T323 417V407H549V293H323V153Z" />
|
||||
<glyph unicode="¤" glyph-name="currency" horiz-adv-x="700" d="M608 257T576 198L678 96L572 -11L467 93Q411 65 349 65Q286 65 232 93L127 -11L22 96L123 198Q91 257 91 322Q91 387 120 440L22 539L127 646L226 548Q283 579 349 579Q416 579 473 548L572
|
||||
646L678 539L579 440Q608 387 608 322Q608 257 576 198ZM395 214T428 245T461 322Q461 367 428 399T349 431Q303 431 271 399T239 322Q239 277 271 246T349 214Q395 214 428 245Z" />
|
||||
<glyph unicode="¥" glyph-name="yen" horiz-adv-x="753" d="M514 311H649V214H475V173H649V76H475V0H277V76H103V173H277V214H103V311H240L-20 700H191L384 414L578 700H773L514 311Z" />
|
||||
<glyph unicode="¦" glyph-name="brokenbar" horiz-adv-x="314" d="M70 742H244V392H70V742ZM70 156H244V-194H70V156Z" />
|
||||
<glyph unicode="§" glyph-name="section" horiz-adv-x="535" d="M509 268T494 237T450 182Q490 142 490 77Q490 23 462 -19T380 -85T250 -109Q186 -109 122 -93T19 -52L72 77Q108 53 158 39T250 24Q286 24 304 36T323 71Q323 95 298 106T219 127Q158 140
|
||||
120 153T53 200T24 290Q24 371 83 419Q44 456 44 522Q44 606 112 657T310 709Q360 709 421 697T518 663L465 534Q392 576 300 576Q211 576 211 529Q211 509 234 499T307 479Q368 466 408 451T479 400T509 303Q509 268 494 237ZM188 286T203 275T239 259T309 242Q326
|
||||
251 335 265T345 297Q345 315 330 326T294 342T224 359Q188 338 188 304Q188 286 203 275Z" />
|
||||
<glyph unicode="¨" glyph-name="dieresis" horiz-adv-x="600" d="M160 606T138 627T115 684Q115 719 137 741T194 763Q228 763 250 741T273 684Q273 649 251 628T194 606Q160 606 138 627ZM372 606T350 627T327 684Q327 719 349 741T406 763Q440 763 462
|
||||
741T485 684Q485 649 463 628T406 606Q372 606 350 627Z" />
|
||||
<glyph unicode="©" glyph-name="copyright" horiz-adv-x="775" d="M288 -3T208 44T81 172T34 350Q34 447 80 528T208 656T388 703Q487 703 567 657T694 531T740 352Q740 254 693 173T565 44T386 -3Q288 -3 208 44ZM463 73T525 110T623 210T659 352Q659 430
|
||||
625 492T528 591T388 627Q310 627 248 591T150 491T115 350Q115 273 150 210T247 110T386 73Q463 73 525 110ZM339 150T290 175T214 246T186 350Q186 408 213 453T290 524T401 550Q464 550 510 522T576 446L468 387Q445 431 400 431Q369 431 348 410T326 350Q326
|
||||
312 347 291T400 269Q445 269 468 313L576 254Q556 206 510 178T401 150Q339 150 290 175Z" />
|
||||
<glyph unicode="ª" glyph-name="ordfeminine" horiz-adv-x="417" d="M373 751T373 600V422H253V464Q227 417 151 417Q90 417 57 445T23 517Q23 613 176 613H243Q238 660 171 660Q148 660 123 653T79 632L37 712Q66 730 108 740T191 751Q373 751 373 600ZM207
|
||||
492T221 500T243 525V551H196Q145 551 145 522Q145 508 156 500T188 492Q207 492 221 500Z" />
|
||||
<glyph unicode="«" glyph-name="guillemotleft" horiz-adv-x="605" d="M31 272L170 469H339L204 272L339 74H170L31 272ZM276 272L415 469H584L449 272L584 74H415L276 272Z" />
|
||||
<glyph unicode="¬" glyph-name="logicalnot" horiz-adv-x="609" d="M551 105H397V278H58V423H551V105Z" />
|
||||
<glyph unicode="­" glyph-name="uni00AD" horiz-adv-x="388" d="M48 358H340V212H48V358Z" />
|
||||
<glyph unicode="®" glyph-name="registered" horiz-adv-x="775" d="M487 703T567 657T694 531T740 352Q740 254 693 173T565 44T386 -3Q288 -3 208 44T81 172T34 350Q34 447 80 528T208 656T388 703Q487 703 567 657ZM623 199T641 248T659 352Q659 430 625
|
||||
492T528 591T388 627Q310 627 248 591T150 491T115 350Q115 273 150 210T247 110T386 73Q446 73 497 95T586 159H465L398 263H351V159H228V541H402Q482 541 528 504T574 402Q574 320 508 285L589 161Q623 199 641 248ZM394 351Q421 351 436 364T452 402Q452 426
|
||||
437 439T394 453H351V351H394Z" />
|
||||
<glyph unicode="¯" glyph-name="overscore" horiz-adv-x="600" d="M103 734H497V632H103V734Z" />
|
||||
<glyph unicode="°" glyph-name="degree" horiz-adv-x="417" d="M159 358T118 381T52 445T27 534Q27 583 51 623T117 686T208 710Q258 710 299 687T365 623T390 534Q390 485 366 445T300 382T208 358Q159 358 118 381ZM245 448T269 472T293 534Q293 570 269
|
||||
594T208 619Q172 619 148 595T124 534Q124 497 148 473T208 448Q245 448 269 472Z" />
|
||||
<glyph unicode="±" glyph-name="plusminus" horiz-adv-x="609" d="M551 518V379H382V221H228V379H58V518H228V676H382V518H551ZM58 145H551V0H58V145Z" />
|
||||
<glyph unicode="²" glyph-name="uni00B2" horiz-adv-x="430" d="M395 426V327H38V406L204 549Q229 570 238 584T247 612Q247 629 233 639T190 650Q163 650 143 640T110 609L13 661Q37 703 85 727T202 751Q283 751 332 716T381 622Q381 590 364 561T301 491L225
|
||||
426H395Z" />
|
||||
<glyph unicode="³" glyph-name="uni00B3" horiz-adv-x="430" d="M346 568T376 536T406 458Q406 421 384 389T316 338T202 318Q147 318 96 330T14 363L59 457Q89 439 126 429T200 419Q272 419 272 458Q272 494 208 494H143V573L221 645H34V742H382V663L290
|
||||
578Q346 568 376 536Z" />
|
||||
<glyph unicode="´" glyph-name="acute" horiz-adv-x="600" d="M336 759H526L338 607H202L336 759Z" />
|
||||
<glyph unicode="µ" glyph-name="uni00B5" horiz-adv-x="695" d="M634 542V0H466V60Q443 24 410 8T338 -9Q287 -9 251 15V-194H61V542H251V270Q251 153 342 153Q387 153 415 184T444 281V542H634Z" />
|
||||
<glyph unicode="¶" glyph-name="paragraph" horiz-adv-x="707" d="M228 347Q167 349 118 373T40 442T11 544Q11 604 42 649T129 718T261 742H637V-100H483V609H382V-100H228V347Z" />
|
||||
<glyph unicode="·" glyph-name="middot" horiz-adv-x="323" d="M111 172T79 203T47 286Q47 337 79 368T161 399Q212 399 243 368T275 286Q275 235 244 204T161 172Q111 172 79 203Z" />
|
||||
<glyph unicode="¸" glyph-name="cedilla" horiz-adv-x="600" d="M238 -236T212 -230T168 -215L194 -140Q224 -154 256 -154Q306 -154 306 -126Q306 -101 261 -101H224L250 9H349L335 -51Q379 -56 400 -78T421 -132Q421 -180 378 -208T263 -236Q238 -236 212 -230Z" />
|
||||
<glyph unicode="¹" glyph-name="uni00B9" horiz-adv-x="430" d="M382 424V327H69V424H164V645H78V742H300V424H382Z" />
|
||||
<glyph unicode="º" glyph-name="ordmasculine" horiz-adv-x="432" d="M160 417T116 438T46 498T20 584Q20 632 45 670T115 729T216 751Q273 751 317 730T387 670T412 584Q412 536 387 498T318 439T216 417Q160 417 116 438ZM246 513T265 532T284 584Q284
|
||||
618 265 636T216 655Q186 655 167 637T148 584Q148 551 167 532T216 513Q246 513 265 532Z" />
|
||||
<glyph unicode="»" glyph-name="guillemotright" horiz-adv-x="605" d="M20 74L155 272L20 469H189L329 272L189 74H20ZM265 74L400 272L265 469H434L574 272L434 74H265Z" />
|
||||
<glyph unicode="¼" glyph-name="onequarter" horiz-adv-x="1050" d="M382 382V285H69V382H164V603H78V700H300V382H382ZM693 700H836L358 0H215L693 700ZM1035 76H977V0H848V76H626V158L808 415H950L779 175H862V238H977V175H1035V76Z" />
|
||||
<glyph unicode="½" glyph-name="onehalf" horiz-adv-x="1050" d="M382 382V285H69V382H164V603H78V700H300V382H382ZM693 700H836L358 0H215L693 700ZM1015 99V0H658V79L824 222Q849 243 858 257T867 285Q867 302 853 312T810 323Q783 323 763 313T730 282L633
|
||||
334Q657 376 705 400T822 424Q903 424 952 389T1001 295Q1001 263 984 234T921 164L845 99H1015Z" />
|
||||
<glyph unicode="¾" glyph-name="threequarters" horiz-adv-x="1050" d="M346 526T376 494T406 416Q406 379 384 347T316 296T202 276Q147 276 96 288T14 321L59 415Q89 397 126 387T200 377Q272 377 272 416Q272 452 208 452H143V531L221 603H34V700H382V621L290
|
||||
536Q346 526 376 494ZM693 700H836L358 0H215L693 700ZM1035 76H977V0H848V76H626V158L808 415H950L779 175H862V238H977V175H1035V76Z" />
|
||||
<glyph unicode="¿" glyph-name="questiondown" horiz-adv-x="597" d="M246 343T214 372T182 446Q182 490 214 520T296 551Q345 551 377 521T409 446Q409 402 378 373T296 343Q246 343 214 372ZM188 -167T116 -118T43 19Q43 60 57 91T90 143T142 192Q176 222
|
||||
191 241T207 287H385Q385 239 363 207T299 135Q270 108 256 90T242 50Q242 23 266 6T330 -11Q370 -11 402 8T455 60L604 -19Q563 -89 488 -128T307 -167Q188 -167 116 -118Z" />
|
||||
<glyph unicode="À" glyph-name="Agrave" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM167 909H357L491 757H355L167 909Z" />
|
||||
<glyph unicode="Á" glyph-name="Aacute" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM429 909H619L431 757H295L429 909Z" />
|
||||
<glyph unicode="Â" glyph-name="Acircumflex" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM479 757L393 833L307 757H181L311 909H475L605 757H479Z" />
|
||||
<glyph unicode="Ã" glyph-name="Atilde" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM444 750T423 760T375 789Q356 802 347 807T327 812Q307 812 295 798T281 759H188Q190 832 224 875T315
|
||||
918Q342 918 363 908T411 880Q430 867 439 862T459 857Q479 857 491 870T505 907H598Q596 836 562 793T471 750Q444 750 423 760Z" />
|
||||
<glyph unicode="Ä" glyph-name="Adieresis" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM253 756T231 777T208 834Q208 869 230 891T287 913Q321 913 343 891T366 834Q366 799 344 778T287
|
||||
756Q253 756 231 777ZM465 756T443 777T420 834Q420 869 442 891T499 913Q533 913 555 891T578 834Q578 799 556 778T499 756Q465 756 443 777Z" />
|
||||
<glyph unicode="Å" glyph-name="Aring" horiz-adv-x="786" d="M539 136H243L188 0H-14L295 700H490L800 0H594L539 136ZM481 282L391 506L301 282H481ZM337 749T299 786T261 876Q261 930 299 967T393 1004Q429 1004 459 987T507 941T525 876Q525 823 487
|
||||
786T393 749Q337 749 299 786ZM417 819T433 835T450 876Q450 901 434 917T393 934Q369 934 353 918T336 876Q336 851 352 835T393 819Q417 819 433 835Z" />
|
||||
<glyph unicode="Æ" glyph-name="AE" horiz-adv-x="1099" d="M1059 153V0H497V136H259L188 0H-14L368 700H1046V547H693V429H1004V281H693V153H1059ZM497 282V547H474L336 282H497Z" />
|
||||
<glyph unicode="Ç" glyph-name="Ccedilla" horiz-adv-x="738" d="M309 -14T222 32T84 162T34 350Q34 455 84 538T221 667T419 714Q515 714 592 680T720 582L594 468Q526 550 429 550Q372 550 328 525T259 455T234 350Q234 291 258 246T327 175T429 150Q526
|
||||
150 594 232L720 118Q669 54 592 20T419 -14Q309 -14 222 32ZM333 -236T307 -230T263 -215L289 -140Q319 -154 351 -154Q401 -154 401 -126Q401 -101 356 -101H319L345 9H444L430 -51Q474 -56 495 -78T516 -132Q516 -180 473 -208T358 -236Q333 -236 307 -230Z"
|
||||
/>
|
||||
<glyph unicode="È" glyph-name="Egrave" d="M632 153V0H70V700H619V547H266V429H577V281H266V153H632ZM119 909H309L443 757H307L119 909Z" />
|
||||
<glyph unicode="É" glyph-name="Eacute" d="M632 153V0H70V700H619V547H266V429H577V281H266V153H632ZM381 909H571L383 757H247L381 909Z" />
|
||||
<glyph unicode="Ê" glyph-name="Ecircumflex" d="M632 153V0H70V700H619V547H266V429H577V281H266V153H632ZM431 757L345 833L259 757H133L263 909H427L557 757H431Z" />
|
||||
<glyph unicode="Ë" glyph-name="Edieresis" d="M632 153V0H70V700H619V547H266V429H577V281H266V153H632ZM205 756T183 777T160 834Q160 869 182 891T239 913Q273 913 295 891T318 834Q318 799 296 778T239 756Q205 756 183 777ZM417 756T395 777T372 834Q372
|
||||
869 394 891T451 913Q485 913 507 891T530 834Q530 799 508 778T451 756Q417 756 395 777Z" />
|
||||
<glyph unicode="Ì" glyph-name="Igrave" horiz-adv-x="339" d="M70 700H268V0H70V700ZM-57 909H133L267 757H131L-57 909Z" />
|
||||
<glyph unicode="Í" glyph-name="Iacute" horiz-adv-x="339" d="M70 700H268V0H70V700ZM205 909H395L207 757H71L205 909Z" />
|
||||
<glyph unicode="Î" glyph-name="Icircumflex" horiz-adv-x="339" d="M70 700H268V0H70V700ZM255 757L169 833L83 757H-43L87 909H251L381 757H255Z" />
|
||||
<glyph unicode="Ï" glyph-name="Idieresis" horiz-adv-x="339" d="M70 700H268V0H70V700ZM29 756T7 777T-16 834Q-16 869 6 891T63 913Q97 913 119 891T142 834Q142 799 120 778T63 756Q29 756 7 777ZM241 756T219 777T196 834Q196 869 218 891T275 913Q309
|
||||
913 331 891T354 834Q354 799 332 778T275 756Q241 756 219 777Z" />
|
||||
<glyph unicode="Ð" glyph-name="Eth" horiz-adv-x="843" d="M87 700H418Q533 700 622 657T760 535T809 350Q809 244 760 165T622 43T418 0H87V700ZM410 158Q500 158 554 209T609 350Q609 440 555 491T410 542H285V158H410ZM-3 416H447V294H-3V416Z" />
|
||||
<glyph unicode="Ñ" glyph-name="Ntilde" horiz-adv-x="806" d="M736 700V0H573L264 373V0H70V700H233L542 327V700H736ZM454 750T433 760T385 789Q366 802 357 807T337 812Q317 812 305 798T291 759H198Q200 832 234 875T325 918Q352 918 373 908T421 880Q440
|
||||
867 449 862T469 857Q489 857 501 870T515 907H608Q606 836 572 793T481 750Q454 750 433 760Z" />
|
||||
<glyph unicode="Ò" glyph-name="Ograve" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612 409
|
||||
587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM197 909H387L521 757H385L197 909Z" />
|
||||
<glyph unicode="Ó" glyph-name="Oacute" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612 409
|
||||
587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM459 909H649L461 757H325L459 909Z" />
|
||||
<glyph unicode="Ô" glyph-name="Ocircumflex" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612
|
||||
409 587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM509 757L423 833L337 757H211L341 909H505L635 757H509Z" />
|
||||
<glyph unicode="Õ" glyph-name="Otilde" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612 409
|
||||
587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM474 750T453 760T405 789Q386 802 377 807T357 812Q337 812 325 798T311 759H218Q220 832 254 875T345 918Q372 918 393 908T441 880Q460 867 469
|
||||
862T489 857Q509 857 521 870T535 907H628Q626 836 592 793T501 750Q474 750 453 760Z" />
|
||||
<glyph unicode="Ö" glyph-name="Odieresis" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612
|
||||
409 587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM283 756T261 777T238 834Q238 869 260 891T317 913Q351 913 373 891T396 834Q396 799 374 778T317 756Q283 756 261 777ZM495 756T473 777T450
|
||||
834Q450 869 472 891T529 913Q563 913 585 891T608 834Q608 799 586 778T529 756Q495 756 473 777Z" />
|
||||
<glyph unicode="×" glyph-name="multiply" horiz-adv-x="609" d="M407 350L530 227L428 124L305 247L182 124L80 227L203 350L80 473L182 576L305 453L428 576L530 473L407 350Z" />
|
||||
<glyph unicode="Ø" glyph-name="Oslash" horiz-adv-x="846" d="M312 -14T224 33T85 163T34 350Q34 454 84 537T223 667T423 714Q534 714 622 667T761 537T812 350Q812 246 762 163T623 33T423 -14Q312 -14 224 33ZM476 150T519 175T587 245T612 350Q612 409
|
||||
587 454T519 525T423 550Q370 550 327 525T259 455T234 350Q234 291 259 246T327 175T423 150Q476 150 519 175ZM663 770H780L183 -70H66L663 770Z" />
|
||||
<glyph unicode="Ù" glyph-name="Ugrave" horiz-adv-x="786" d="M237 -14T151 71T64 312V700H262V318Q262 150 395 150Q527 150 527 318V700H722V312Q722 156 636 71T393 -14Q237 -14 151 71ZM169 909H359L493 757H357L169 909Z" />
|
||||
<glyph unicode="Ú" glyph-name="Uacute" horiz-adv-x="786" d="M237 -14T151 71T64 312V700H262V318Q262 150 395 150Q527 150 527 318V700H722V312Q722 156 636 71T393 -14Q237 -14 151 71ZM431 909H621L433 757H297L431 909Z" />
|
||||
<glyph unicode="Û" glyph-name="Ucircumflex" horiz-adv-x="786" d="M237 -14T151 71T64 312V700H262V318Q262 150 395 150Q527 150 527 318V700H722V312Q722 156 636 71T393 -14Q237 -14 151 71ZM481 757L395 833L309 757H183L313 909H477L607 757H481Z" />
|
||||
<glyph unicode="Ü" glyph-name="Udieresis" horiz-adv-x="786" d="M237 -14T151 71T64 312V700H262V318Q262 150 395 150Q527 150 527 318V700H722V312Q722 156 636 71T393 -14Q237 -14 151 71ZM255 756T233 777T210 834Q210 869 232 891T289 913Q323 913
|
||||
345 891T368 834Q368 799 346 778T289 756Q255 756 233 777ZM467 756T445 777T422 834Q422 869 444 891T501 913Q535 913 557 891T580 834Q580 799 558 778T501 756Q467 756 445 777Z" />
|
||||
<glyph unicode="Ý" glyph-name="Yacute" horiz-adv-x="693" d="M445 251V0H247V254L-20 700H189L355 422L521 700H713L445 251ZM382 909H572L384 757H248L382 909Z" />
|
||||
<glyph unicode="Þ" glyph-name="Thorn" horiz-adv-x="737" d="M485 628T555 597T663 507T701 369Q701 290 663 232T555 142T390 110H268V0H70V701H268V628H390Q485 628 555 597ZM439 267T470 293T501 369Q501 418 470 444T378 471H268V267H378Q439 267 470 293Z" />
|
||||
<glyph unicode="ß" glyph-name="germandbls" horiz-adv-x="703" d="M607 371T642 324T677 210Q677 108 607 50T419 -9Q387 -9 354 -5T299 7L319 154Q354 142 394 142Q435 142 459 161T484 215Q484 250 459 268T385 287H332V433Q378 435 405 458T432 521Q432
|
||||
557 409 579T346 601Q302 601 277 576T251 502V0H61V478Q61 565 98 626T201 719T346 751Q429 751 489 723T582 647T614 537Q614 452 544 394Q607 371 642 324Z" />
|
||||
<glyph unicode="à" glyph-name="agrave" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427 551
|
||||
498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM87 759H277L411 607H275L87 759Z" />
|
||||
<glyph unicode="á" glyph-name="aacute" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427 551
|
||||
498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM349 759H539L351 607H215L349 759Z" />
|
||||
<glyph unicode="â" glyph-name="acircumflex" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427
|
||||
551 498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM399 607L313 683L227 607H101L231 759H395L525 607H399Z" />
|
||||
<glyph unicode="ã" glyph-name="atilde" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427 551
|
||||
498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM364 600T343 610T295 639Q276 652 267 657T247 662Q227 662 215 648T201 609H108Q110 682 144 725T235 768Q262 768 283 758T331 730Q350 717 359 712T379
|
||||
707Q399 707 411 720T425 757H518Q516 686 482 643T391 600Q364 600 343 610Z" />
|
||||
<glyph unicode="ä" glyph-name="adieresis" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427
|
||||
551 498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM173 606T151 627T128 684Q128 719 150 741T207 763Q241 763 263 741T286 684Q286 649 264 628T207 606Q173 606 151 627ZM385 606T363 627T340 684Q340
|
||||
719 362 741T419 763Q453 763 475 741T498 684Q498 649 476 628T419 606Q385 606 363 627Z" />
|
||||
<glyph unicode="å" glyph-name="aring" horiz-adv-x="628" d="M427 551T498 490T569 301V0H392V70Q351 -9 232 -9Q169 -9 123 13T54 72T30 158Q30 235 89 277T271 320H379Q374 406 264 406Q225 406 185 394T117 359L53 488Q98 518 162 534T292 551Q427 551
|
||||
498 490ZM318 111T343 127T379 174V221H297Q214 221 214 166Q214 141 233 126T285 111Q318 111 343 127ZM257 591T219 628T181 718Q181 772 219 809T313 846Q349 846 379 829T427 783T445 718Q445 665 407 628T313 591Q257 591 219 628ZM337 661T353 677T370 718Q370
|
||||
743 354 759T313 776Q289 776 273 760T256 718Q256 693 272 677T313 661Q337 661 353 677Z" />
|
||||
<glyph unicode="æ" glyph-name="ae" horiz-adv-x="999" d="M972 245T969 222H575Q586 181 620 159T706 136Q742 136 772 147T832 183L932 79Q850 -9 703 -9Q633 -9 573 12T470 79Q406 -9 266 -9Q156 -9 93 38T30 164Q30 238 89 280T271 322H379Q376 362 348
|
||||
384T265 406Q224 406 185 394T117 359L53 488Q99 518 162 534T291 551Q422 551 489 483Q528 516 578 533T684 551Q762 551 828 518T933 421T972 274Q972 245 969 222ZM640 416T610 391T571 322H790Q783 366 753 391T681 416Q640 416 610 391ZM330 111T354 135T379
|
||||
200V222H297Q214 222 214 168Q214 141 233 126T287 111Q330 111 354 135Z" />
|
||||
<glyph unicode="ç" glyph-name="ccedilla" horiz-adv-x="603" d="M248 -9T177 27T67 127T27 272Q27 353 66 416T177 515T338 551Q430 551 497 512T592 402L445 327Q408 400 337 400Q286 400 253 366T219 272Q219 211 252 177T337 142Q408 142 445 215L592
|
||||
140Q564 70 497 31T338 -9Q248 -9 177 27ZM250 -236T224 -230T180 -215L206 -140Q236 -154 268 -154Q318 -154 318 -126Q318 -101 273 -101H236L262 9H361L347 -51Q391 -56 412 -78T433 -132Q433 -180 390 -208T275 -236Q250 -236 224 -230Z" />
|
||||
<glyph unicode="è" glyph-name="egrave" horiz-adv-x="642" d="M615 268T612 223H218Q230 181 264 159T351 136Q390 136 418 147T476 183L576 79Q497 -9 345 -9Q250 -9 178 27T67 127T27 272Q27 352 65 415T172 515T325 551Q406 551 472 518T576 421T615
|
||||
270Q615 268 612 223ZM282 416T253 391T215 323H437Q429 366 400 391T326 416Q282 416 253 391ZM95 759H285L419 607H283L95 759Z" />
|
||||
<glyph unicode="é" glyph-name="eacute" horiz-adv-x="642" d="M615 268T612 223H218Q230 181 264 159T351 136Q390 136 418 147T476 183L576 79Q497 -9 345 -9Q250 -9 178 27T67 127T27 272Q27 352 65 415T172 515T325 551Q406 551 472 518T576 421T615
|
||||
270Q615 268 612 223ZM282 416T253 391T215 323H437Q429 366 400 391T326 416Q282 416 253 391ZM357 759H547L359 607H223L357 759Z" />
|
||||
<glyph unicode="ê" glyph-name="ecircumflex" horiz-adv-x="642" d="M615 268T612 223H218Q230 181 264 159T351 136Q390 136 418 147T476 183L576 79Q497 -9 345 -9Q250 -9 178 27T67 127T27 272Q27 352 65 415T172 515T325 551Q406 551 472 518T576 421T615
|
||||
270Q615 268 612 223ZM282 416T253 391T215 323H437Q429 366 400 391T326 416Q282 416 253 391ZM407 607L321 683L235 607H109L239 759H403L533 607H407Z" />
|
||||
<glyph unicode="ë" glyph-name="edieresis" horiz-adv-x="642" d="M615 268T612 223H218Q230 181 264 159T351 136Q390 136 418 147T476 183L576 79Q497 -9 345 -9Q250 -9 178 27T67 127T27 272Q27 352 65 415T172 515T325 551Q406 551 472 518T576 421T615
|
||||
270Q615 268 612 223ZM282 416T253 391T215 323H437Q429 366 400 391T326 416Q282 416 253 391ZM181 606T159 627T136 684Q136 719 158 741T215 763Q249 763 271 741T294 684Q294 649 272 628T215 606Q181 606 159 627ZM393 606T371 627T348 684Q348 719 370 741T427
|
||||
763Q461 763 483 741T506 684Q506 649 484 628T427 606Q393 606 371 627Z" />
|
||||
<glyph unicode="ì" glyph-name="igrave" horiz-adv-x="313" d="M61 542H251V0H61V542ZM-70 759H120L254 607H118L-70 759Z" />
|
||||
<glyph unicode="í" glyph-name="iacute" horiz-adv-x="313" d="M61 542H251V0H61V542ZM192 759H382L194 607H58L192 759Z" />
|
||||
<glyph unicode="î" glyph-name="icircumflex" horiz-adv-x="313" d="M61 542H251V0H61V542ZM218 607L156 676L94 607H-31L76 759H236L343 607H218Z" />
|
||||
<glyph unicode="ï" glyph-name="idieresis" horiz-adv-x="313" d="M61 542H251V0H61V542ZM37 606T16 628T-5 684Q-5 718 16 740T69 762Q100 762 121 740T142 684Q142 649 121 628T69 606Q37 606 16 628ZM212 606T191 628T170 684Q170 718 191 740T244 762Q275
|
||||
762 296 740T317 684Q317 649 296 628T244 606Q212 606 191 628Z" />
|
||||
<glyph unicode="ð" glyph-name="eth" horiz-adv-x="666" d="M639 508T639 340Q639 230 598 151T482 29T306 -14Q228 -14 164 15T64 99T27 225Q27 291 60 342T151 421T277 449Q380 449 440 392Q437 494 391 547L147 457L114 542L282 605Q259 609 228 609Q160
|
||||
609 100 589L80 731Q160 749 238 749Q387 749 488 682L580 716L613 630L562 611Q639 508 639 340ZM366 127T395 152T424 217Q424 257 395 282T322 308Q277 308 249 284T220 217Q220 176 248 152T321 127Q366 127 395 152Z" />
|
||||
<glyph unicode="ñ" glyph-name="ntilde" horiz-adv-x="696" d="M515 551T576 491T638 310V0H448V279Q448 390 359 390Q310 390 281 358T251 262V0H61V542H242V483Q274 516 318 533T414 551Q515 551 576 491ZM403 600T382 610T334 639Q315 652 306 657T286
|
||||
662Q266 662 254 648T240 609H147Q149 682 183 725T274 768Q301 768 322 758T370 730Q389 717 398 712T418 707Q438 707 450 720T464 757H557Q555 686 521 643T430 600Q403 600 382 610Z" />
|
||||
<glyph unicode="ò" glyph-name="ograve" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333
|
||||
400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM105 759H295L429 607H293L105 759Z" />
|
||||
<glyph unicode="ó" glyph-name="oacute" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333
|
||||
400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM367 759H557L369 607H233L367 759Z" />
|
||||
<glyph unicode="ô" glyph-name="ocircumflex" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415
|
||||
366T333 400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM417 607L331 683L245 607H119L249 759H413L543 607H417Z" />
|
||||
<glyph unicode="õ" glyph-name="otilde" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333
|
||||
400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM382 600T361 610T313 639Q294 652 285 657T265 662Q245 662 233 648T219 609H126Q128 682 162 725T253 768Q280 768 301 758T349 730Q368 717 377 712T397 707Q417 707 429 720T443 757H536Q534
|
||||
686 500 643T409 600Q382 600 361 610Z" />
|
||||
<glyph unicode="ö" glyph-name="odieresis" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333
|
||||
400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM191 606T169 627T146 684Q146 719 168 741T225 763Q259 763 281 741T304 684Q304 649 282 628T225 606Q191 606 169 627ZM403 606T381 627T358 684Q358 719 380 741T437 763Q471 763 493
|
||||
741T516 684Q516 649 494 628T437 606Q403 606 381 627Z" />
|
||||
<glyph unicode="÷" glyph-name="divide" horiz-adv-x="609" d="M263 469T236 496T208 565Q208 607 235 633T305 660Q346 660 374 634T402 565Q402 523 374 496T305 469Q263 469 236 496ZM58 423H551V277H58V423ZM263 40T236 67T208 137Q208 179 235 205T305
|
||||
231Q346 231 374 205T402 137Q402 95 374 68T305 40Q263 40 236 67Z" />
|
||||
<glyph unicode="ø" glyph-name="oslash" horiz-adv-x="666" d="M246 -9T176 27T67 127T27 272Q27 352 66 416T175 515T333 551Q421 551 491 516T600 417T639 272Q639 191 600 127T491 27T333 -9Q246 -9 176 27ZM383 142T415 176T447 272Q447 332 415 366T333
|
||||
400Q283 400 251 366T219 272Q219 211 251 177T333 142Q383 142 415 176ZM508 607H594L153 -70H67L508 607Z" />
|
||||
<glyph unicode="ù" glyph-name="ugrave" horiz-adv-x="692" d="M631 542V0H450V58Q420 25 378 8T289 -9Q184 -9 122 53T59 239V542H249V270Q249 209 272 181T339 153Q384 153 412 184T441 281V542H631ZM119 759H309L443 607H307L119 759Z" />
|
||||
<glyph unicode="ú" glyph-name="uacute" horiz-adv-x="692" d="M631 542V0H450V58Q420 25 378 8T289 -9Q184 -9 122 53T59 239V542H249V270Q249 209 272 181T339 153Q384 153 412 184T441 281V542H631ZM381 759H571L383 607H247L381 759Z" />
|
||||
<glyph unicode="û" glyph-name="ucircumflex" horiz-adv-x="692" d="M631 542V0H450V58Q420 25 378 8T289 -9Q184 -9 122 53T59 239V542H249V270Q249 209 272 181T339 153Q384 153 412 184T441 281V542H631ZM431 607L345 683L259 607H133L263 759H427L557 607H431Z" />
|
||||
<glyph unicode="ü" glyph-name="udieresis" horiz-adv-x="692" d="M631 542V0H450V58Q420 25 378 8T289 -9Q184 -9 122 53T59 239V542H249V270Q249 209 272 181T339 153Q384 153 412 184T441 281V542H631ZM205 606T183 627T160 684Q160 719 182 741T239 763Q273
|
||||
763 295 741T318 684Q318 649 296 628T239 606Q205 606 183 627ZM417 606T395 627T372 684Q372 719 394 741T451 763Q485 763 507 741T530 684Q530 649 508 628T451 606Q417 606 395 627Z" />
|
||||
<glyph unicode="ý" glyph-name="yacute" horiz-adv-x="620" d="M632 542L398 -22Q357 -122 298 -162T154 -203Q111 -203 68 -190T-3 -154L63 -21Q79 -36 101 -44T147 -53Q174 -53 191 -42T221 -7L-11 542H184L317 211L451 542H632ZM336 759H526L338 607H202L336
|
||||
759Z" />
|
||||
<glyph unicode="þ" glyph-name="thorn" horiz-adv-x="695" d="M476 551T536 517T632 419T668 271Q668 187 633 124T537 26T402 -9Q307 -9 251 48V-194H61V742H251V498Q304 551 402 551Q476 551 536 517ZM412 142T444 176T476 271Q476 331 444 365T362 400Q312
|
||||
400 280 366T248 271Q248 211 280 177T362 142Q412 142 444 176Z" />
|
||||
<glyph unicode="ÿ" glyph-name="ydieresis" horiz-adv-x="620" d="M632 542L398 -22Q357 -122 298 -162T154 -203Q111 -203 68 -190T-3 -154L63 -21Q79 -36 101 -44T147 -53Q174 -53 191 -42T221 -7L-11 542H184L317 211L451 542H632ZM160 606T138 627T115
|
||||
684Q115 719 137 741T194 763Q228 763 250 741T273 684Q273 649 251 628T194 606Q160 606 138 627ZM372 606T350 627T327 684Q327 719 349 741T406 763Q440 763 462 741T485 684Q485 649 463 628T406 606Q372 606 350 627Z" />
|
||||
<glyph unicode="–" glyph-name="endash" horiz-adv-x="500" d="M0 342H500V229H0V342Z" />
|
||||
<glyph unicode="—" glyph-name="emdash" horiz-adv-x="1000" d="M0 342H1000V229H0V342Z" />
|
||||
<glyph unicode="‘" glyph-name="quoteleft" horiz-adv-x="283" d="M224 566T239 541T255 481Q255 431 223 400T141 369Q91 369 59 400T27 481Q27 504 33 527T60 595L124 742H243L196 579Q224 566 239 541Z" />
|
||||
<glyph unicode="’" glyph-name="quoteright" horiz-adv-x="283" d="M191 751T223 720T255 639Q255 616 249 593T223 524L159 378H40L87 541Q59 554 44 579T28 639Q28 689 60 720T142 751Q191 751 223 720Z" />
|
||||
<glyph unicode="‚" glyph-name="quotesinglbase" horiz-adv-x="283" d="M191 216T223 185T255 104Q255 81 249 58T222 -11L159 -157H40L87 6Q59 19 44 44T28 104Q28 154 60 185T142 216Q191 216 223 185Z" />
|
||||
<glyph unicode="“" glyph-name="quotedblleft" horiz-adv-x="545" d="M224 566T239 541T255 481Q255 431 223 400T141 369Q91 369 59 400T27 481Q27 504 33 527T60 595L124 742H243L196 579Q224 566 239 541ZM486 566T501 541T517 481Q517 431 485 400T403
|
||||
369Q353 369 321 400T289 481Q289 504 295 527T322 595L386 742H505L458 579Q486 566 501 541Z" />
|
||||
<glyph unicode="”" glyph-name="quotedblright" horiz-adv-x="545" d="M191 751T223 720T255 639Q255 616 249 593T223 524L159 378H40L87 541Q59 554 44 579T28 639Q28 689 60 720T142 751Q191 751 223 720ZM453 751T485 720T517 639Q517 616 511 593T485
|
||||
524L421 378H302L349 541Q321 554 306 579T290 639Q290 689 322 720T404 751Q453 751 485 720Z" />
|
||||
<glyph unicode="„" glyph-name="quotedblbase" horiz-adv-x="545" d="M191 216T223 185T255 104Q255 81 249 58T222 -11L159 -157H40L87 6Q59 19 44 44T28 104Q28 154 60 185T142 216Q191 216 223 185ZM453 216T485 185T517 104Q517 81 511 58T484 -11L421
|
||||
-157H302L349 6Q321 19 306 44T290 104Q290 154 322 185T404 216Q453 216 485 185Z" />
|
||||
<glyph unicode="•" glyph-name="bullet" horiz-adv-x="383" d="M151 137T118 156T66 208T47 283Q47 324 66 357T118 408T191 427Q231 427 264 409T316 357T336 283Q336 242 317 209T264 156T191 137Q151 137 118 156Z" />
|
||||
<glyph unicode="‹" glyph-name="guilsinglleft" horiz-adv-x="360" d="M31 272L170 469H339L204 272L339 74H170L31 272Z" />
|
||||
<glyph unicode="›" glyph-name="guilsinglright" horiz-adv-x="360" d="M20 74L155 272L20 469H189L329 272L189 74H20Z" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 52 KiB |
@ -30,7 +30,7 @@ export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
|
||||
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
|
||||
export const NOTIFICATIONS_MARK_READ = 'NOTIFICATIONS_MARK_READ';
|
||||
|
||||
export const MAX_QUEUED_NOTIFICATIONS = 40;
|
||||
export const MAX_QUEUED_NOTIFICATIONS = 40
|
||||
|
||||
defineMessages({
|
||||
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
|
||||
@ -43,12 +43,12 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
|
||||
if (accountIds.length > 0) {
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function initializeNotifications() {
|
||||
return {
|
||||
type: NOTIFICATIONS_INITIALIZE,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function updateNotifications(notification, intlMessages, intlLocale) {
|
||||
|
@ -40,7 +40,7 @@ class Avatar extends ImmutablePureComponent {
|
||||
const shouldAnimate = animate || !sameImg
|
||||
|
||||
const options = {
|
||||
className: [_s.default, _s.circle].join(' '),
|
||||
className: [_s.default, _s.circle, _s.overflowHidden].join(' '),
|
||||
onMouseEnter: shouldAnimate ? this.handleMouseEnter : undefined,
|
||||
onMouseLeave: shouldAnimate ? this.handleMouseLeave : undefined,
|
||||
src: account.get((hovering || animate) ? 'avatar' : 'avatar_static'),
|
||||
|
@ -20,7 +20,7 @@ export default class Badge extends PureComponent {
|
||||
|
||||
render() {
|
||||
const { children, description } = this.props
|
||||
const { hovering } = this.state
|
||||
const { hovering } = this.state // : todo : tooltip
|
||||
|
||||
return (
|
||||
<Text
|
||||
|
35
app/javascript/gabsocial/components/comment.js
Normal file
@ -0,0 +1,35 @@
|
||||
import { Fragment } from 'react'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { me } from '../initial_state'
|
||||
import Avatar from './avatar'
|
||||
import DisplayName from './display_name'
|
||||
import Button from './button'
|
||||
import Text from './text'
|
||||
|
||||
const messages = defineMessages({
|
||||
follow: { id: 'follow', defaultMessage: 'Follow' },
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class Comment extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
//
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,7 @@ class DisplayName extends ImmutablePureComponent {
|
||||
multiline: PropTypes.bool,
|
||||
large: PropTypes.bool,
|
||||
noHover: PropTypes.bool,
|
||||
noUsername: PropTypes.bool,
|
||||
}
|
||||
|
||||
handleMouseEnter = debounce(() => {
|
||||
@ -41,7 +42,13 @@ class DisplayName extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, multiline, large, noHover } = this.props
|
||||
const {
|
||||
account,
|
||||
multiline,
|
||||
large,
|
||||
noHover,
|
||||
noUsername
|
||||
} = this.props
|
||||
|
||||
if (!account) return null
|
||||
|
||||
@ -114,9 +121,12 @@ class DisplayName extends ImmutablePureComponent {
|
||||
<Icon id='verified' width='16px' height='16px' className={_s.default} title='Gab Investor' />
|
||||
*/ }
|
||||
</div>
|
||||
<span className={usernameClasses}>
|
||||
@{account.get('acct')}
|
||||
</span>
|
||||
{
|
||||
!noUsername &&
|
||||
<span className={usernameClasses}>
|
||||
@{account.get('acct')}
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
import { Fragment } from 'react'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { shortNumberFormat } from '../../utils/numbers'
|
||||
import PanelLayout from './panel_layout'
|
||||
import Button from '../button'
|
||||
import Divider from '../divider'
|
||||
import Heading from '../heading'
|
||||
import Icon from '../icon'
|
||||
import Text from '../text'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'notification_filters', defaultMessage: 'Notification Filters' },
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class NotificationFilterPanel extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props
|
||||
|
||||
// date
|
||||
// verfied or not
|
||||
// specific user
|
||||
// specific status
|
||||
// only people i do/not follow
|
||||
|
||||
return (
|
||||
<PanelLayout title={intl.formatMessage(messages.title)}>
|
||||
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,5 +1,39 @@
|
||||
export default class StatusOptionsPopover extends PureComponent {
|
||||
render() {
|
||||
|
||||
// if (publicStatus) {
|
||||
// menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
|
||||
// menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
// menu.push(null);
|
||||
// }
|
||||
|
||||
// if (me === status.getIn(['account', 'id'])) {
|
||||
// if (publicStatus) {
|
||||
// menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
// } else {
|
||||
// if (status.get('visibility') === 'private') {
|
||||
// menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_reblog_private : messages.reblog_private), action: this.handleReblogClick });
|
||||
// }
|
||||
// }
|
||||
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
|
||||
// } else {
|
||||
// menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
// if (isStaff) {
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
// menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
// }
|
||||
// }
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ /* */ }
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { throttle } from 'lodash';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import IntersectionObserverArticleContainer from '../containers/intersection_observer_article_container';
|
||||
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper';
|
||||
import ColumnIndicator from './column_indicator';
|
||||
import LoadMore from './load_more';
|
||||
import { throttle } from 'lodash'
|
||||
import { List as ImmutableList } from 'immutable'
|
||||
import IntersectionObserverArticle from './intersection_observer_article'
|
||||
import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper'
|
||||
import ColumnIndicator from './column_indicator'
|
||||
import LoadMore from './load_more'
|
||||
|
||||
const MOUSE_IDLE_DELAY = 300;
|
||||
const MOUSE_IDLE_DELAY = 300
|
||||
|
||||
export default class ScrollableList extends PureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
scrollKey: PropTypes.string.isRequired,
|
||||
@ -23,11 +23,11 @@ export default class ScrollableList extends PureComponent {
|
||||
children: PropTypes.node,
|
||||
onScrollToTop: PropTypes.func,
|
||||
onScroll: PropTypes.func,
|
||||
};
|
||||
}
|
||||
|
||||
state = {
|
||||
cachedMediaWidth: 250, // Default media/card width using default Gab Social theme
|
||||
};
|
||||
}
|
||||
|
||||
intersectionObserverWrapper = new IntersectionObserverWrapper();
|
||||
|
||||
@ -213,7 +213,7 @@ export default class ScrollableList extends PureComponent {
|
||||
<div className='scrollable-list' onMouseMove={this.handleMouseMove}>
|
||||
<div role='feed'>
|
||||
{React.Children.map(this.props.children, (child, index) => (
|
||||
<IntersectionObserverArticleContainer
|
||||
<IntersectionObserverArticle
|
||||
key={child.key}
|
||||
id={child.key}
|
||||
index={index}
|
||||
@ -227,7 +227,7 @@ export default class ScrollableList extends PureComponent {
|
||||
cachedMediaWidth: this.state.cachedMediaWidth,
|
||||
cacheMediaWidth: this.cacheMediaWidth,
|
||||
})}
|
||||
</IntersectionObserverArticleContainer>
|
||||
</IntersectionObserverArticle>
|
||||
))}
|
||||
|
||||
{loadMore}
|
||||
|
@ -272,9 +272,9 @@ class Status extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
let media = null;
|
||||
let statusAvatar, prepend, rebloggedByText, reblogContent;
|
||||
let prepend, rebloggedByText, reblogContent;
|
||||
|
||||
const { intl, hidden, featured, otherAccounts, unread, showThread, group, promoted } = this.props;
|
||||
const { intl, hidden, featured, unread, showThread, group, promoted } = this.props;
|
||||
|
||||
// console.log("replies:", this.props.replies)
|
||||
|
||||
@ -321,7 +321,7 @@ class Status extends ImmutablePureComponent {
|
||||
prepend = (
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.paddingVertical5PX, _s.paddingHorizontal15PX].join(' ')}>
|
||||
<Icon
|
||||
id='pin'
|
||||
id='star'
|
||||
width='10px'
|
||||
height='10px'
|
||||
className={_s.fillColorSecondary}
|
||||
@ -366,7 +366,7 @@ class Status extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
if (status.get('poll')) {
|
||||
media = <Poll pollId={status.get('poll')} />;
|
||||
media = <Poll pollId={status.get('poll')} />
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
const video = status.getIn(['media_attachments', 0]);
|
||||
@ -375,6 +375,7 @@ class Status extends ImmutablePureComponent {
|
||||
<Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer}>
|
||||
{Component => (
|
||||
<Component
|
||||
inline
|
||||
preview={video.get('preview_url')}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
@ -382,7 +383,6 @@ class Status extends ImmutablePureComponent {
|
||||
aspectRatio={video.getIn(['meta', 'small', 'aspect'])}
|
||||
width={this.props.cachedMediaWidth}
|
||||
height={110}
|
||||
inline
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
cacheWidth={this.props.cacheMediaWidth}
|
||||
@ -391,7 +391,7 @@ class Status extends ImmutablePureComponent {
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
)
|
||||
} else {
|
||||
media = (
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
|
||||
@ -408,10 +408,10 @@ class Status extends ImmutablePureComponent {
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
)
|
||||
}
|
||||
} else if (status.get('spoiler_text').length === 0 && status.get('card')) {
|
||||
console.log("card:", status.get('card'))
|
||||
// console.log("card:", status.get('card'))
|
||||
media = (
|
||||
<Card
|
||||
onOpenMedia={this.props.onOpenMedia}
|
||||
@ -419,23 +419,21 @@ class Status extends ImmutablePureComponent {
|
||||
cacheWidth={this.props.cacheMediaWidth}
|
||||
defaultWidth={this.props.cachedMediaWidth}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
const handlers = this.props.muted
|
||||
? {}
|
||||
: {
|
||||
reply: this.handleHotkeyReply,
|
||||
favourite: this.handleHotkeyFavourite,
|
||||
boost: this.handleHotkeyBoost,
|
||||
mention: this.handleHotkeyMention,
|
||||
open: this.handleHotkeyOpen,
|
||||
openProfile: this.handleHotkeyOpenProfile,
|
||||
moveUp: this.handleHotkeyMoveUp,
|
||||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
};
|
||||
const handlers = this.props.muted ? {} : {
|
||||
reply: this.handleHotkeyReply,
|
||||
favourite: this.handleHotkeyFavourite,
|
||||
boost: this.handleHotkeyBoost,
|
||||
mention: this.handleHotkeyMention,
|
||||
open: this.handleHotkeyOpen,
|
||||
openProfile: this.handleHotkeyOpenProfile,
|
||||
moveUp: this.handleHotkeyMoveUp,
|
||||
moveDown: this.handleHotkeyMoveDown,
|
||||
toggleHidden: this.handleHotkeyToggleHidden,
|
||||
toggleSensitive: this.handleHotkeyToggleSensitive,
|
||||
}
|
||||
|
||||
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`;
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
import { Provider } from 'react-redux';
|
||||
import { IntlProvider, addLocaleData } from 'react-intl';
|
||||
import { getLocale } from '../locales';
|
||||
import configureStore from '../store/configureStore';
|
||||
import { hydrateStore } from '../actions/store';
|
||||
import { fetchCustomEmojis } from '../actions/custom_emojis';
|
||||
import initialState from '../initial_state';
|
||||
import Compose from '../features/standalone/compose';
|
||||
|
||||
const { localeData, messages } = getLocale();
|
||||
addLocaleData(localeData);
|
||||
|
||||
const store = configureStore();
|
||||
|
||||
if (initialState) {
|
||||
store.dispatch(hydrateStore(initialState));
|
||||
}
|
||||
|
||||
store.dispatch(fetchCustomEmojis());
|
||||
|
||||
export default class TimelineContainer extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
locale: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
render () {
|
||||
const { locale } = this.props;
|
||||
|
||||
return (
|
||||
<IntlProvider locale={locale} messages={messages}>
|
||||
<Provider store={store}>
|
||||
<Compose />
|
||||
</Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { setHeight } from '../actions/height_cache';
|
||||
import IntersectionObserverArticle from '../components/intersection_observer_article';
|
||||
|
||||
const makeMapStateToProps = (state, props) => ({
|
||||
cachedHeight: state.getIn(['height_cache', props.saveHeightKey, props.id]),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onHeightChange (key, id, height) {
|
||||
dispatch(setHeight(key, id, height));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(IntersectionObserverArticle);
|
@ -1,55 +0,0 @@
|
||||
import { Fragment } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Provider } from 'react-redux';
|
||||
import { IntlProvider, addLocaleData } from 'react-intl';
|
||||
import { getLocale } from '../locales';
|
||||
import configureStore from '../store/configureStore';
|
||||
import { hydrateStore } from '../actions/store';
|
||||
import initialState from '../initial_state';
|
||||
import PublicTimeline from '../features/standalone/public_timeline';
|
||||
import HashtagTimeline from '../features/standalone/hashtag_timeline';
|
||||
import ModalRoot from '../components/modal/modal_root'
|
||||
|
||||
const { localeData, messages } = getLocale();
|
||||
addLocaleData(localeData);
|
||||
|
||||
const store = configureStore();
|
||||
|
||||
if (initialState) {
|
||||
store.dispatch(hydrateStore(initialState));
|
||||
}
|
||||
|
||||
export default class TimelineContainer extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
locale: PropTypes.string.isRequired,
|
||||
hashtag: PropTypes.string,
|
||||
local: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
local: !initialState.settings.known_fediverse,
|
||||
};
|
||||
|
||||
render () {
|
||||
const { locale, hashtag, local } = this.props;
|
||||
|
||||
const timeline = hashtag ? <HashtagTimeline hashtag={hashtag} /> : <PublicTimeline local={local} />;
|
||||
|
||||
return (
|
||||
<IntlProvider locale={locale} messages={messages}>
|
||||
<Provider store={store}>
|
||||
<Fragment>
|
||||
{timeline}
|
||||
|
||||
{ReactDOM.createPortal(
|
||||
<ModalContainer />,
|
||||
document.getElementById('modal-container'),
|
||||
)}
|
||||
</Fragment>
|
||||
</Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,7 @@ const messages = defineMessages({
|
||||
error: { id: 'empty_column.account_unavailable', defaultMessage: 'Profile unavailable' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state, { params: { username } }) => {
|
||||
const mapStateToProps = (state, { mediaType, params: { username } }) => {
|
||||
const accounts = state.getIn(['accounts']);
|
||||
const accountFetchError = (state.getIn(['accounts', -1, 'username'], '').toLowerCase() == username.toLowerCase());
|
||||
|
||||
@ -67,7 +67,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
|
||||
disabled={this.props.disabled}
|
||||
onClick={this.handleLoadMore}
|
||||
/>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@ -86,11 +86,11 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
isAccount: PropTypes.bool,
|
||||
unavailable: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
state = {
|
||||
width: 323,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { params: { username }, accountId } = this.props;
|
||||
@ -158,27 +158,29 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
const { width } = this.state;
|
||||
|
||||
if (!isAccount && accountId !== -1) {
|
||||
return (<ColumnIndicator type='missing' />);
|
||||
return <ColumnIndicator type='missing' />
|
||||
} else if (accountId === -1 || (!attachments && isLoading)) {
|
||||
return (<ColumnIndicator type='loading' />);
|
||||
return <ColumnIndicator type='loading' />
|
||||
} else if (unavailable) {
|
||||
return (<ColumnIndicator type='error' message={intl.formatMessage(messages.error)} />);
|
||||
return <ColumnIndicator type='error' message={intl.formatMessage(messages.error)} />
|
||||
}
|
||||
|
||||
let loadOlder = null;
|
||||
let loadOlder = null
|
||||
|
||||
if (hasMore && !(isLoading && attachments.size === 0)) {
|
||||
loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />;
|
||||
loadOlder = <LoadMore visible={!isLoading} onClick={this.handleLoadOlder} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='scrollable-list scrollable-list--flex' onScroll={this.handleScroll}>
|
||||
<div role='feed' className='account-gallery__container' ref={this.handleRef}>
|
||||
{attachments.map((attachment, index) => attachment === null ? (
|
||||
<LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} />
|
||||
) : (
|
||||
{
|
||||
attachments.map((attachment, index) => attachment === null ? (
|
||||
<LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} />
|
||||
) : (
|
||||
<MediaItem key={attachment.get('id')} attachment={attachment} displayWidth={width} onOpenMedia={this.handleOpenMedia} />
|
||||
))}
|
||||
))
|
||||
}
|
||||
|
||||
{
|
||||
attachments.size == 0 &&
|
||||
@ -190,11 +192,12 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
{loadOlder}
|
||||
</div>
|
||||
|
||||
{isLoading && attachments.size === 0 && (
|
||||
{
|
||||
isLoading && attachments.size === 0 &&
|
||||
<div className='slist__append'>
|
||||
<ColumnIndicator type='loading' />
|
||||
</div>
|
||||
)}
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ class Header extends ImmutablePureComponent {
|
||||
}} />
|
||||
</Button>
|
||||
}
|
||||
<DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
|
||||
{/*<DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />*/}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ const mapStateToProps = state => {
|
||||
timelineId,
|
||||
allFediverse,
|
||||
onlyMedia,
|
||||
// hasUnread: state.getIn(['timelines', `${timelineId}${onlyMedia ? ':media' : ''}`, 'unread']) > 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +38,6 @@ class CommunityTimeline extends PureComponent {
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
// hasUnread: PropTypes.bool,
|
||||
onlyMedia: PropTypes.bool,
|
||||
allFediverse: PropTypes.bool,
|
||||
timelineId: PropTypes.string,
|
||||
|
@ -52,7 +52,7 @@ class ActionBar extends PureComponent {
|
||||
return (
|
||||
<div style={{'marginTop':'-6px'}}>
|
||||
<div>
|
||||
<DropdownMenuContainer items={menu} icon='chevron-down' size={size} direction='right' />
|
||||
{ /* <DropdownMenuContainer items={menu} icon='chevron-down' size={size} direction='right' /> */ }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
70
app/javascript/gabsocial/features/favorites/favorites.js
Normal file
@ -0,0 +1,70 @@
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { fetchReblogs } from '../../actions/interactions';
|
||||
import { fetchStatus } from '../../actions/statuses';
|
||||
import { makeGetStatus } from '../../selectors';
|
||||
import AccountContainer from '../../containers/account_container';
|
||||
import ColumnIndicator from '../../components/column_indicator';
|
||||
import ScrollableList from '../../components/scrollable_list';
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const getStatus = makeGetStatus();
|
||||
const status = getStatus(state, {
|
||||
id: props.params.statusId,
|
||||
username: props.params.username,
|
||||
});
|
||||
|
||||
return {
|
||||
status,
|
||||
accountIds: state.getIn(['user_lists', 'favorites', props.params.statusId]),
|
||||
};
|
||||
};
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
class Favorites extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
accountIds: ImmutablePropTypes.list,
|
||||
status: ImmutablePropTypes.map,
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
this.props.dispatch(fetchReblogs(this.props.params.statusId));
|
||||
this.props.dispatch(fetchStatus(this.props.params.statusId));
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) {
|
||||
this.props.dispatch(fetchReblogs(nextProps.params.statusId));
|
||||
this.props.dispatch(fetchStatus(nextProps.params.statusId));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { accountIds, status } = this.props;
|
||||
|
||||
if (!accountIds) {
|
||||
return <ColumnIndicator type='loading' />
|
||||
} else if (!status) {
|
||||
return <ColumnIndicator type='missing' />
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollableList
|
||||
scrollKey='reblogs'
|
||||
emptyMessage={<FormattedMessage id='status.reblogs.empty' defaultMessage='No one has reposted this gab yet. When someone does, they will show up here.' />}
|
||||
>
|
||||
{
|
||||
accountIds.map(id =>
|
||||
<AccountContainer key={id} id={id} withNote={false} />
|
||||
)
|
||||
}
|
||||
</ScrollableList>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
1
app/javascript/gabsocial/features/favorites/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './favorites'
|
@ -72,7 +72,10 @@ class GroupMembers extends ImmutablePureComponent {
|
||||
return (
|
||||
<div className="group-account-wrapper" key={id}>
|
||||
<AccountContainer id={id} withNote={false} actionIcon="none" onActionClick={() => true} />
|
||||
{menu.length > 0 && <DropdownMenuContainer items={menu} icon='ellipsis-h' size={18} direction='right' />}
|
||||
{ /*
|
||||
menu.length > 0 && <DropdownMenuContainer items={menu} icon='ellipsis-h' size={18} direction='right' />
|
||||
*/
|
||||
}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
@ -45,7 +45,8 @@ getActionButton() {
|
||||
{ text: intl.formatMessage(messages.removed_accounts), to: `/groups/${group.get('id')}/removed_accounts` },
|
||||
];
|
||||
|
||||
return <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
|
||||
// <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />;
|
||||
return <div></div>
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isEqual } from 'lodash';
|
||||
import { expandHashtagTimeline, clearTimeline } from '../../actions/timelines';
|
||||
import { connectHashtagStream } from '../../actions/streaming';
|
||||
import StatusListContainer from '../../containers/status_list_container';
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import { isEqual } from 'lodash'
|
||||
import { expandHashtagTimeline, clearTimeline } from '../../actions/timelines'
|
||||
import { connectHashtagStream } from '../../actions/streaming'
|
||||
import StatusListContainer from '../../containers/status_list_container'
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0,
|
||||
});
|
||||
})
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
@ -18,88 +18,114 @@ class HashtagTimeline extends PureComponent {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
hasUnread: PropTypes.bool,
|
||||
};
|
||||
}
|
||||
|
||||
title = () => {
|
||||
let title = [this.props.params.id];
|
||||
let title = [this.props.params.id]
|
||||
|
||||
if (this.additionalFor('any')) {
|
||||
title.push(' ', <FormattedMessage key='any' id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />);
|
||||
title.push(' ',
|
||||
<FormattedMessage
|
||||
key='any'
|
||||
id='hashtag.column_header.tag_mode.any'
|
||||
values={{
|
||||
additional: this.additionalFor('any')
|
||||
}}
|
||||
defaultMessage='or {additional}'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (this.additionalFor('all')) {
|
||||
title.push(' ', <FormattedMessage key='all' id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />);
|
||||
title.push(' ',
|
||||
<FormattedMessage
|
||||
key='all'
|
||||
id='hashtag.column_header.tag_mode.all'
|
||||
values={{
|
||||
additional: this.additionalFor('all')
|
||||
}}
|
||||
defaultMessage='and {additional}'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (this.additionalFor('none')) {
|
||||
title.push(' ', <FormattedMessage key='none' id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage='without {additional}' />);
|
||||
title.push(' ',
|
||||
<FormattedMessage
|
||||
key='none'
|
||||
id='hashtag.column_header.tag_mode.none'
|
||||
values={{
|
||||
additional: this.additionalFor('none')
|
||||
}}
|
||||
defaultMessage='without {additional}'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return title;
|
||||
return title
|
||||
}
|
||||
|
||||
additionalFor = (mode) => {
|
||||
const { tags } = this.props.params;
|
||||
const { tags } = this.props.params
|
||||
|
||||
try {
|
||||
return tags[mode].map(tag => tag.value).join('/');
|
||||
return tags[mode].map(tag => tag.value).join('/')
|
||||
} catch (error) {
|
||||
return '';
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
_subscribe (dispatch, id, tags = {}) {
|
||||
let any = (tags.any || []).map(tag => tag.value);
|
||||
let all = (tags.all || []).map(tag => tag.value);
|
||||
let any = (tags.any || []).map(tag => tag.value)
|
||||
let all = (tags.all || []).map(tag => tag.value)
|
||||
let none = (tags.none || []).map(tag => tag.value);
|
||||
|
||||
[id, ...any].map(tag => {
|
||||
this.disconnects.push(dispatch(connectHashtagStream(id, tag, status => {
|
||||
let tags = status.tags.map(tag => tag.name);
|
||||
let tags = status.tags.map(tag => tag.name)
|
||||
|
||||
return all.filter(tag => tags.includes(tag)).length === all.length &&
|
||||
none.filter(tag => tags.includes(tag)).length === 0;
|
||||
})));
|
||||
});
|
||||
none.filter(tag => tags.includes(tag)).length === 0
|
||||
})))
|
||||
})
|
||||
}
|
||||
|
||||
_unsubscribe () {
|
||||
this.disconnects.map(disconnect => disconnect());
|
||||
this.disconnects = [];
|
||||
this.disconnects.map(disconnect => disconnect())
|
||||
this.disconnects = []
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch } = this.props;
|
||||
const { id, tags } = this.props.params;
|
||||
const { dispatch } = this.props
|
||||
const { id, tags } = this.props.params
|
||||
|
||||
this._subscribe(dispatch, id, tags);
|
||||
dispatch(expandHashtagTimeline(id, { tags }));
|
||||
this._subscribe(dispatch, id, tags)
|
||||
dispatch(expandHashtagTimeline(id, { tags }))
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
const { dispatch, params } = this.props;
|
||||
const { id, tags } = nextProps.params;
|
||||
const { dispatch, params } = this.props
|
||||
const { id, tags } = nextProps.params
|
||||
|
||||
if (id !== params.id || !isEqual(tags, params.tags)) {
|
||||
this._unsubscribe();
|
||||
this._subscribe(dispatch, id, tags);
|
||||
this.props.dispatch(clearTimeline(`hashtag:${id}`));
|
||||
this.props.dispatch(expandHashtagTimeline(id, { tags }));
|
||||
this._unsubscribe()
|
||||
this._subscribe(dispatch, id, tags)
|
||||
this.props.dispatch(clearTimeline(`hashtag:${id}`))
|
||||
this.props.dispatch(expandHashtagTimeline(id, { tags }))
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this._unsubscribe();
|
||||
this._unsubscribe()
|
||||
}
|
||||
|
||||
handleLoadMore = maxId => {
|
||||
const { id, tags } = this.props.params;
|
||||
this.props.dispatch(expandHashtagTimeline(id, { maxId, tags }));
|
||||
const { id, tags } = this.props.params
|
||||
this.props.dispatch(expandHashtagTimeline(id, { maxId, tags }))
|
||||
}
|
||||
|
||||
render () {
|
||||
const { hasUnread } = this.props;
|
||||
const { id } = this.props.params;
|
||||
const { id } = this.props.params
|
||||
|
||||
return (
|
||||
<StatusListContainer
|
||||
|
@ -1,11 +1,18 @@
|
||||
import { injectIntl, FormattedMessage } from 'react-intl'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { HotKeys } from 'react-hotkeys'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import StatusContainer from '../../../../containers/status_container'
|
||||
import AccountContainer from '../../../../containers/account_container'
|
||||
import Button from '../../../../components/button'
|
||||
import Avatar from '../../../../components/avatar'
|
||||
import Icon from '../../../../components/icon'
|
||||
import Text from '../../../../components/text'
|
||||
import DisplayName from '../../../../components/display_name'
|
||||
|
||||
const messages = defineMessages({
|
||||
|
||||
})
|
||||
|
||||
const notificationForScreenReader = (intl, message, timestamp) => {
|
||||
const output = [message]
|
||||
@ -33,18 +40,115 @@ class Notification extends ImmutablePureComponent {
|
||||
renderFavorite = () => {
|
||||
const { status, notificationType, accounts } = this.props
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.paddingHorizontal10PX].join(' ')}>
|
||||
<div className={[_s.default, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.marginVertical10PX, _s.paddingVertical10PX, _s.paddingHorizontal10PX].join(' ')}>
|
||||
|
||||
<Icon id='apps' height='20px' width='20px' className={_s.marginTop5PX} />
|
||||
|
||||
<div className={[_s.default, _s.marginLeft15PX].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||
{
|
||||
accounts.slice(0, 6).map((account, i) => (
|
||||
<NavLink
|
||||
to={`/${account.get('acct')}`}
|
||||
key={`fav-avatar-${i}`}
|
||||
className={_s.marginRight5PX}
|
||||
>
|
||||
<Avatar size='30' account={account} />
|
||||
</NavLink>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div className={[_s.default, _s.paddingTop10PX].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||
<div className={_s.text}>
|
||||
{
|
||||
accounts.slice(0, 1).map((account, i) => (
|
||||
<DisplayName key={i} account={account} noUsername />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<Text size='medium'>
|
||||
and 3 others favorited your gab
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={[_s.default, _s.paddingTop10PX].join(' ')}>
|
||||
<Text color='secondary' size='medium'>
|
||||
post this at 1-14-2020 12:15pm (edited)
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { notification } = this.props
|
||||
const account = notification.get('account')
|
||||
const {
|
||||
status,
|
||||
notificationType,
|
||||
accounts,
|
||||
intl
|
||||
} = this.props
|
||||
|
||||
switch (notification.get('type')) {
|
||||
case 'favourite':
|
||||
return this.renderFavorite()
|
||||
}
|
||||
// const linkTo = '/admin/posts/123/reblogs' // etc.
|
||||
|
||||
return null
|
||||
return (
|
||||
<NavLink
|
||||
to={`/`}
|
||||
className={[_s.default, _s.paddingHorizontal10PX, _s.backgroundSubtle_onHover].join(' ')}
|
||||
>
|
||||
<div className={[_s.default, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.marginVertical10PX, _s.paddingVertical10PX, _s.paddingHorizontal10PX].join(' ')}>
|
||||
|
||||
<Icon id='apps' height='20px' width='20px' className={_s.marginTop5PX} />
|
||||
|
||||
<div className={[_s.default, _s.marginLeft15PX].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||
{
|
||||
accounts.slice(0, 6).map((account, i) => (
|
||||
<NavLink
|
||||
to={`/${account.get('acct')}`}
|
||||
key={`fav-avatar-${i}`}
|
||||
className={_s.marginRight5PX}
|
||||
>
|
||||
<Avatar size='30' account={account} />
|
||||
</NavLink>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div className={[_s.default, _s.paddingTop10PX].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow].join(' ')}>
|
||||
<div className={_s.text}>
|
||||
{
|
||||
accounts.slice(0, 1).map((account, i) => (
|
||||
<DisplayName key={i} account={account} noUsername />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<Text size='medium'>
|
||||
and 3 others favorited your gab
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={[_s.default, _s.paddingTop10PX].join(' ')}>
|
||||
<Text color='secondary' size='medium'>
|
||||
post this at 1-14-2020 12:15pm (edited)
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</NavLink>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,70 +1,74 @@
|
||||
import { openModal } from '../../../actions/modal';
|
||||
import { mentionCompose } from '../../../actions/compose';
|
||||
import { openModal } from '../../../actions/modal'
|
||||
import { mentionCompose } from '../../../actions/compose'
|
||||
import {
|
||||
reblog,
|
||||
favourite,
|
||||
unreblog,
|
||||
unfavourite,
|
||||
} from '../../../actions/interactions';
|
||||
} from '../../../actions/interactions'
|
||||
import {
|
||||
hideStatus,
|
||||
revealStatus,
|
||||
} from '../../../actions/statuses';
|
||||
import { boostModal } from '../../../initial_state';
|
||||
import { makeGetNotification, makeGetStatus } from '../../../selectors';
|
||||
import Notification from '../components/notification/notification';
|
||||
} from '../../../actions/statuses'
|
||||
import { boostModal, me } from '../../../initial_state'
|
||||
import { makeGetNotification, makeGetStatus } from '../../../selectors'
|
||||
import Notification from '../components/notification/notification-alt'
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getNotification = makeGetNotification();
|
||||
const getStatus = makeGetStatus();
|
||||
const getNotification = makeGetNotification()
|
||||
const getStatus = makeGetStatus()
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const notification = getNotification(state, props.notification, props.accountId);
|
||||
const notification = getNotification(state, props.notification, props.accountId)
|
||||
|
||||
const account = state.getIn(['accounts', me])
|
||||
|
||||
return {
|
||||
accounts: [account, account, account],
|
||||
notification: notification,
|
||||
status: notification.get('status') ? getStatus(state, { id: notification.get('status') }) : null,
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
return mapStateToProps
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onMention: (account, router) => {
|
||||
dispatch(mentionCompose(account, router));
|
||||
dispatch(mentionCompose(account, router))
|
||||
},
|
||||
|
||||
onModalReblog (status) {
|
||||
dispatch(reblog(status));
|
||||
dispatch(reblog(status))
|
||||
},
|
||||
|
||||
onReblog (status, e) {
|
||||
if (status.get('reblogged')) {
|
||||
dispatch(unreblog(status));
|
||||
dispatch(unreblog(status))
|
||||
} else {
|
||||
if (e.shiftKey || !boostModal) {
|
||||
this.onModalReblog(status);
|
||||
this.onModalReblog(status)
|
||||
} else {
|
||||
dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
|
||||
dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onFavourite (status) {
|
||||
if (status.get('favourited')) {
|
||||
dispatch(unfavourite(status));
|
||||
dispatch(unfavourite(status))
|
||||
} else {
|
||||
dispatch(favourite(status));
|
||||
dispatch(favourite(status))
|
||||
}
|
||||
},
|
||||
|
||||
onToggleHidden (status) {
|
||||
if (status.get('hidden')) {
|
||||
dispatch(revealStatus(status.get('id')));
|
||||
dispatch(revealStatus(status.get('id')))
|
||||
} else {
|
||||
dispatch(hideStatus(status.get('id')));
|
||||
dispatch(hideStatus(status.get('id')))
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(Notification);
|
||||
export default connect(makeMapStateToProps, mapDispatchToProps)(Notification)
|
||||
|
@ -1,19 +1,20 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import { createSelector } from 'reselect';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { debounce } from 'lodash';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
|
||||
import { createSelector } from 'reselect'
|
||||
import { List as ImmutableList } from 'immutable'
|
||||
import { debounce } from 'lodash'
|
||||
import {
|
||||
expandNotifications,
|
||||
scrollTopNotifications,
|
||||
dequeueNotifications,
|
||||
} from '../../actions/notifications';
|
||||
import NotificationContainer from './containers/notification_container';
|
||||
// import ColumnSettingsContainer from './containers/column_settings_container';
|
||||
import ScrollableList from '../../components/scrollable_list';
|
||||
import LoadMore from '../../components/load_more';
|
||||
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
|
||||
} from '../../actions/notifications'
|
||||
import NotificationContainer from './containers/notification_container'
|
||||
// import ColumnSettingsContainer from './containers/column_settings_container'
|
||||
import ScrollableList from '../../components/scrollable_list'
|
||||
import LoadMore from '../../components/load_more'
|
||||
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header'
|
||||
import Block from '../../components/block'
|
||||
|
||||
const getNotifications = createSelector([
|
||||
state => state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
|
||||
@ -25,10 +26,10 @@ const getNotifications = createSelector([
|
||||
// used if user changed the notification settings after loading the notifications from the server
|
||||
// otherwise a list of notifications will come pre-filtered from the backend
|
||||
// we need to turn it off for FilterBar in order not to block ourselves from seeing a specific category
|
||||
return notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')));
|
||||
return notifications.filterNot(item => item !== null && excludedTypes.includes(item.get('type')))
|
||||
}
|
||||
return notifications.filter(item => item !== null && allowedType === item.get('type'));
|
||||
});
|
||||
return notifications.filter(item => item !== null && allowedType === item.get('type'))
|
||||
})
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
|
||||
@ -37,7 +38,7 @@ const mapStateToProps = state => ({
|
||||
isUnread: state.getIn(['notifications', 'unread']) > 0,
|
||||
hasMore: state.getIn(['notifications', 'hasMore']),
|
||||
totalQueuedNotificationsCount: state.getIn(['notifications', 'totalQueuedNotificationsCount'], 0),
|
||||
});
|
||||
})
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
@ -54,73 +55,81 @@ class Notifications extends ImmutablePureComponent {
|
||||
hasMore: PropTypes.bool,
|
||||
dequeueNotifications: PropTypes.func,
|
||||
totalQueuedNotificationsCount: PropTypes.number,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.handleLoadOlder.cancel();
|
||||
this.handleScrollToTop.cancel();
|
||||
this.handleScroll.cancel();
|
||||
this.props.dispatch(scrollTopNotifications(false));
|
||||
this.handleLoadOlder.cancel()
|
||||
this.handleScrollToTop.cancel()
|
||||
this.handleScroll.cancel()
|
||||
this.props.dispatch(scrollTopNotifications(false))
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleDequeueNotifications();
|
||||
this.props.dispatch(scrollTopNotifications(true));
|
||||
this.handleDequeueNotifications()
|
||||
this.props.dispatch(scrollTopNotifications(true))
|
||||
}
|
||||
|
||||
handleLoadGap = (maxId) => {
|
||||
this.props.dispatch(expandNotifications({ maxId }));
|
||||
};
|
||||
this.props.dispatch(expandNotifications({ maxId }))
|
||||
}
|
||||
|
||||
handleLoadOlder = debounce(() => {
|
||||
const last = this.props.notifications.last();
|
||||
this.props.dispatch(expandNotifications({ maxId: last && last.get('id') }));
|
||||
}, 300, { leading: true });
|
||||
const last = this.props.notifications.last()
|
||||
this.props.dispatch(expandNotifications({ maxId: last && last.get('id') }))
|
||||
}, 300, { leading: true })
|
||||
|
||||
handleScrollToTop = debounce(() => {
|
||||
this.props.dispatch(scrollTopNotifications(true));
|
||||
}, 100);
|
||||
this.props.dispatch(scrollTopNotifications(true))
|
||||
}, 100)
|
||||
|
||||
handleScroll = debounce(() => {
|
||||
this.props.dispatch(scrollTopNotifications(false));
|
||||
}, 100);
|
||||
this.props.dispatch(scrollTopNotifications(false))
|
||||
}, 100)
|
||||
|
||||
setColumnRef = c => {
|
||||
this.column = c;
|
||||
this.column = c
|
||||
}
|
||||
|
||||
handleMoveUp = id => {
|
||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1;
|
||||
this._selectChild(elementIndex, true);
|
||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1
|
||||
this._selectChild(elementIndex, true)
|
||||
}
|
||||
|
||||
handleMoveDown = id => {
|
||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1;
|
||||
this._selectChild(elementIndex, false);
|
||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1
|
||||
this._selectChild(elementIndex, false)
|
||||
}
|
||||
|
||||
_selectChild (index, align_top) {
|
||||
const container = this.column.node;
|
||||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
|
||||
const container = this.column.node
|
||||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`)
|
||||
|
||||
if (element) {
|
||||
if (align_top && container.scrollTop > element.offsetTop) {
|
||||
element.scrollIntoView(true);
|
||||
element.scrollIntoView(true)
|
||||
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
|
||||
element.scrollIntoView(false);
|
||||
element.scrollIntoView(false)
|
||||
}
|
||||
element.focus();
|
||||
element.focus()
|
||||
}
|
||||
}
|
||||
|
||||
handleDequeueNotifications = () => {
|
||||
this.props.dispatch(dequeueNotifications());
|
||||
};
|
||||
this.props.dispatch(dequeueNotifications())
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, notifications, isLoading, isUnread, hasMore, showFilterBar, totalQueuedNotificationsCount } = this.props;
|
||||
const {
|
||||
intl,
|
||||
notifications,
|
||||
isLoading,
|
||||
isUnread,
|
||||
hasMore,
|
||||
showFilterBar,
|
||||
totalQueuedNotificationsCount
|
||||
} = this.props
|
||||
|
||||
let scrollableContent = null;
|
||||
let scrollableContent = null
|
||||
|
||||
// : todo : include follow requests
|
||||
|
||||
@ -157,7 +166,7 @@ class Notifications extends ImmutablePureComponent {
|
||||
console.log('filteredNotifications:', filteredNotifications)
|
||||
|
||||
if (isLoading && this.scrollableContent) {
|
||||
scrollableContent = this.scrollableContent;
|
||||
scrollableContent = this.scrollableContent
|
||||
} else if (notifications.size > 0 || hasMore) {
|
||||
scrollableContent = notifications.map((item, index) => item === null ? (
|
||||
<LoadMore
|
||||
@ -169,18 +178,17 @@ class Notifications extends ImmutablePureComponent {
|
||||
/>
|
||||
) : (
|
||||
<NotificationContainer
|
||||
key={item.get('id')}
|
||||
key={`notification-${index}`}
|
||||
notification={item}
|
||||
accountId={item.get('account')}
|
||||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
/>
|
||||
));
|
||||
))
|
||||
} else {
|
||||
scrollableContent = null;
|
||||
scrollableContent = null
|
||||
}
|
||||
|
||||
this.scrollableContent = scrollableContent;
|
||||
this.scrollableContent = scrollableContent
|
||||
|
||||
return (
|
||||
<div ref={this.setColumnRef}>
|
||||
@ -191,18 +199,20 @@ class Notifications extends ImmutablePureComponent {
|
||||
itemType='notification'
|
||||
/>
|
||||
|
||||
<ScrollableList
|
||||
scrollKey='notifications'
|
||||
isLoading={isLoading}
|
||||
showLoading={isLoading && notifications.size === 0}
|
||||
hasMore={hasMore}
|
||||
emptyMessage={<FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />}
|
||||
onLoadMore={this.handleLoadOlder}
|
||||
onScrollToTop={this.handleScrollToTop}
|
||||
onScroll={this.handleScroll}
|
||||
>
|
||||
{ scrollableContent }
|
||||
</ScrollableList>
|
||||
<Block>
|
||||
<ScrollableList
|
||||
scrollKey='notifications'
|
||||
isLoading={isLoading}
|
||||
showLoading={isLoading && notifications.size === 0}
|
||||
hasMore={hasMore}
|
||||
emptyMessage={<FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />}
|
||||
onLoadMore={this.handleLoadOlder}
|
||||
onScrollToTop={this.handleScrollToTop}
|
||||
onScroll={this.handleScroll}
|
||||
>
|
||||
{ scrollableContent }
|
||||
</ScrollableList>
|
||||
</Block>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
import ComposeFormContainer from '../../compose/containers/compose_form_container';
|
||||
import NotificationsContainer from '../../../containers/notifications_container';
|
||||
import LoadingBarContainer from '../../../containers/loading_bar_container';
|
||||
import ModalRoot from '../../../components/modal/modal_root'
|
||||
|
||||
export default class Compose extends PureComponent {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<ComposeFormContainer />
|
||||
<NotificationsContainer />
|
||||
<ModalRoot />
|
||||
<LoadingBarContainer className='loading-bar' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './compose'
|
@ -1,83 +0,0 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Masonry from 'react-masonry-infinite';
|
||||
import { List as ImmutableList } from 'immutable';
|
||||
import { debounce } from 'lodash';
|
||||
import { expandHashtagTimeline } from '../../../actions/timelines';
|
||||
import DetailedStatusContainer from '../../../features/status/containers/detailed_status_container';
|
||||
import ColumnIndicator from '../../../components/column_indicator';
|
||||
|
||||
const mapStateToProps = (state, { hashtag }) => ({
|
||||
statusIds: state.getIn(['timelines', `hashtag:${hashtag}`, 'items'], ImmutableList()),
|
||||
isLoading: state.getIn(['timelines', `hashtag:${hashtag}`, 'isLoading'], false),
|
||||
hasMore: state.getIn(['timelines', `hashtag:${hashtag}`, 'hasMore'], false),
|
||||
});
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
class HashtagTimeline extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
statusIds: ImmutablePropTypes.list.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
hasMore: PropTypes.bool.isRequired,
|
||||
hashtag: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { dispatch, hashtag } = this.props;
|
||||
|
||||
dispatch(expandHashtagTimeline(hashtag));
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
const maxId = this.props.statusIds.last();
|
||||
|
||||
if (maxId) {
|
||||
this.props.dispatch(expandHashtagTimeline(this.props.hashtag, { maxId }));
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.masonry = c;
|
||||
}
|
||||
|
||||
handleHeightChange = debounce(() => {
|
||||
if (!this.masonry) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.masonry.forcePack();
|
||||
}, 50)
|
||||
|
||||
render () {
|
||||
const { statusIds, hasMore, isLoading } = this.props;
|
||||
|
||||
const sizes = [
|
||||
{ columns: 1, gutter: 0 },
|
||||
{ mq: '415px', columns: 1, gutter: 10 },
|
||||
{ mq: '640px', columns: 2, gutter: 10 },
|
||||
{ mq: '960px', columns: 3, gutter: 10 },
|
||||
{ mq: '1255px', columns: 3, gutter: 10 },
|
||||
];
|
||||
|
||||
const loader = (isLoading && statusIds.isEmpty()) ? <ColumnIndicator type='loading' key={0} /> : undefined;
|
||||
|
||||
return (
|
||||
<Masonry ref={this.setRef} className='statuses-grid' hasMore={hasMore} loadMore={this.handleLoadMore} sizes={sizes} loader={loader}>
|
||||
{statusIds.map(statusId => (
|
||||
<div className='statuses-grid__item' key={statusId}>
|
||||
<DetailedStatusContainer
|
||||
id={statusId}
|
||||
compact
|
||||
measureHeight
|
||||
onHeightChange={this.handleHeightChange}
|
||||
/>
|
||||
</div>
|
||||
)).toArray()}
|
||||
</Masonry>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './hashtag_timeline'
|
@ -1 +0,0 @@
|
||||
export { default } from './public_timeline'
|
@ -1,98 +0,0 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Masonry from 'react-masonry-infinite';
|
||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||
import { debounce } from 'lodash';
|
||||
import { expandPublicTimeline, expandCommunityTimeline } from '../../../actions/timelines';
|
||||
import DetailedStatusContainer from '../../../features/status/containers/detailed_status_container';
|
||||
import ColumnIndicator from '../../../components/column_indicator';
|
||||
|
||||
const mapStateToProps = (state, { local }) => {
|
||||
const timeline = state.getIn(['timelines', local ? 'community' : 'public'], ImmutableMap());
|
||||
|
||||
return {
|
||||
statusIds: timeline.get('items', ImmutableList()),
|
||||
isLoading: timeline.get('isLoading', false),
|
||||
hasMore: timeline.get('hasMore', false),
|
||||
};
|
||||
};
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps)
|
||||
class PublicTimeline extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
statusIds: ImmutablePropTypes.list.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
hasMore: PropTypes.bool.isRequired,
|
||||
local: PropTypes.bool,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
this._connect();
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
if (prevProps.local !== this.props.local) {
|
||||
this._connect();
|
||||
}
|
||||
}
|
||||
|
||||
_connect () {
|
||||
const { dispatch, local } = this.props;
|
||||
|
||||
dispatch(local ? expandCommunityTimeline() : expandPublicTimeline());
|
||||
}
|
||||
|
||||
handleLoadMore = () => {
|
||||
const { dispatch, statusIds, local } = this.props;
|
||||
const maxId = statusIds.last();
|
||||
|
||||
if (maxId) {
|
||||
dispatch(local ? expandCommunityTimeline({ maxId }) : expandPublicTimeline({ maxId }));
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.masonry = c;
|
||||
}
|
||||
|
||||
handleHeightChange = debounce(() => {
|
||||
if (!this.masonry) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.masonry.forcePack();
|
||||
}, 50)
|
||||
|
||||
render () {
|
||||
const { statusIds, hasMore, isLoading } = this.props;
|
||||
|
||||
const sizes = [
|
||||
{ columns: 1, gutter: 0 },
|
||||
{ mq: '415px', columns: 1, gutter: 10 },
|
||||
{ mq: '640px', columns: 2, gutter: 10 },
|
||||
{ mq: '960px', columns: 3, gutter: 10 },
|
||||
{ mq: '1255px', columns: 3, gutter: 10 },
|
||||
];
|
||||
|
||||
const loader = (isLoading && statusIds.isEmpty()) ? <ColumnIndicator type='loading' key={0} /> : undefined;
|
||||
|
||||
return (
|
||||
<Masonry ref={this.setRef} className='statuses-grid' hasMore={hasMore} loadMore={this.handleLoadMore} sizes={sizes} loader={loader}>
|
||||
{statusIds.map(statusId => (
|
||||
<div className='statuses-grid__item' key={statusId}>
|
||||
<DetailedStatusContainer
|
||||
id={statusId}
|
||||
compact
|
||||
measureHeight
|
||||
onHeightChange={this.handleHeightChange}
|
||||
/>
|
||||
</div>
|
||||
)).toArray()}
|
||||
</Masonry>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -124,7 +124,7 @@ export default class Card extends ImmutablePureComponent {
|
||||
return (
|
||||
<div
|
||||
ref={this.setRef}
|
||||
className={[_s.default, _s.backgroundcolorSecondary3, _s.positionAbsolute, _s.top0, _s.right0, _s.bottom0, _s.left0, _s.statusCardVideo].join(' ')}
|
||||
className={[_s.default, _s.backgroundColorSecondary3, _s.positionAbsolute, _s.top0, _s.right0, _s.bottom0, _s.left0, _s.statusCardVideo].join(' ')}
|
||||
dangerouslySetInnerHTML={content}
|
||||
/>
|
||||
)
|
||||
|
@ -1,218 +0,0 @@
|
||||
import { Link, NavLink } from 'react-router-dom';
|
||||
import { FormattedDate, FormattedNumber } from 'react-intl';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import classNames from 'classnames';
|
||||
import scheduleIdleTask from '../../../../utils/schedule_idle_task';
|
||||
import StatusQuote from '../../../../components/status_quote';
|
||||
import Avatar from '../../../../components/avatar';
|
||||
import DisplayName from '../../../../components/display_name';
|
||||
import StatusContent from '../../../../components/status_content';
|
||||
import MediaGallery from '../../../../components/media_gallery';
|
||||
import Icon from '../../../../components/icon';
|
||||
import Poll from '../../../../components/poll';
|
||||
import Card from '../card';
|
||||
import Video from '../../../video';
|
||||
|
||||
export default class DetailedStatus extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map,
|
||||
onOpenMedia: PropTypes.func.isRequired,
|
||||
onOpenVideo: PropTypes.func.isRequired,
|
||||
onToggleHidden: PropTypes.func.isRequired,
|
||||
measureHeight: PropTypes.bool,
|
||||
onHeightChange: PropTypes.func,
|
||||
domain: PropTypes.string.isRequired,
|
||||
compact: PropTypes.bool,
|
||||
showMedia: PropTypes.bool,
|
||||
onToggleMediaVisibility: PropTypes.func,
|
||||
onShowRevisions: PropTypes.func,
|
||||
};
|
||||
|
||||
state = {
|
||||
height: null,
|
||||
};
|
||||
|
||||
handleShowRevisions = () => {
|
||||
this.props.onShowRevisions(this.props.status);
|
||||
}
|
||||
|
||||
handleOpenVideo = (media, startTime) => {
|
||||
this.props.onOpenVideo(media, startTime);
|
||||
}
|
||||
|
||||
handleExpandedToggle = () => {
|
||||
this.props.onToggleHidden(this.props.status);
|
||||
}
|
||||
|
||||
_measureHeight (heightJustChanged) {
|
||||
if (this.props.measureHeight && this.node) {
|
||||
scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 }));
|
||||
|
||||
if (this.props.onHeightChange && heightJustChanged) {
|
||||
this.props.onHeightChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setRef = c => {
|
||||
this.node = c;
|
||||
this._measureHeight();
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps, prevState) {
|
||||
this._measureHeight(prevState.height !== this.state.height);
|
||||
}
|
||||
|
||||
handleModalLink = e => {
|
||||
e.preventDefault();
|
||||
|
||||
let href;
|
||||
|
||||
if (e.target.nodeName !== 'A') {
|
||||
href = e.target.parentNode.href;
|
||||
} else {
|
||||
href = e.target.href;
|
||||
}
|
||||
|
||||
window.open(href, 'gabsocial-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
|
||||
}
|
||||
|
||||
render () {
|
||||
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
|
||||
const outerStyle = { boxSizing: 'border-box' };
|
||||
const { compact } = this.props;
|
||||
|
||||
if (!status) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let media = '';
|
||||
let applicationLink = '';
|
||||
let reblogLink = '';
|
||||
let reblogIcon = 'retweet';
|
||||
let favouriteLink = '';
|
||||
|
||||
if (this.props.measureHeight) {
|
||||
outerStyle.height = `${this.state.height}px`;
|
||||
}
|
||||
|
||||
if (status.get('poll')) {
|
||||
media = <Poll pollId={status.get('poll')} />;
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
const video = status.getIn(['media_attachments', 0]);
|
||||
|
||||
media = (
|
||||
<Video
|
||||
preview={video.get('preview_url')}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
alt={video.get('description')}
|
||||
aspectRatio={video.getIn(['meta', 'small', 'aspect'])}
|
||||
width={300}
|
||||
height={150}
|
||||
inline
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
sensitive={status.get('sensitive')}
|
||||
visible={this.props.showMedia}
|
||||
onToggleVisibility={this.props.onToggleMediaVisibility}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
media = (
|
||||
<MediaGallery
|
||||
standalone
|
||||
sensitive={status.get('sensitive')}
|
||||
media={status.get('media_attachments')}
|
||||
height={300}
|
||||
onOpenMedia={this.props.onOpenMedia}
|
||||
visible={this.props.showMedia}
|
||||
onToggleVisibility={this.props.onToggleMediaVisibility}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (status.get('spoiler_text').length === 0) {
|
||||
media = <Card onOpenMedia={this.props.onOpenMedia} card={status.get('card', null)} />;
|
||||
}
|
||||
|
||||
if (status.get('application')) {
|
||||
applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener'>{status.getIn(['application', 'name'])}</a></span>;
|
||||
}
|
||||
|
||||
if (status.get('visibility') === 'direct') {
|
||||
reblogIcon = 'envelope';
|
||||
} else if (status.get('visibility') === 'private') {
|
||||
reblogIcon = 'lock';
|
||||
}
|
||||
|
||||
if (status.get('visibility') === 'private') {
|
||||
reblogLink = <Icon id={reblogIcon} />;
|
||||
} else if (this.context.router) {
|
||||
reblogLink = (
|
||||
<Link to={`/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}/reblogs`} className='detailed-status__link'>
|
||||
<Icon id={reblogIcon} />
|
||||
<span className='detailed-status__reblogs'>
|
||||
<FormattedNumber value={status.get('reblogs_count')} />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
} else {
|
||||
reblogLink = (
|
||||
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
|
||||
<Icon id={reblogIcon} />
|
||||
<span className='detailed-status__reblogs'>
|
||||
<FormattedNumber value={status.get('reblogs_count')} />
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
favouriteLink = (
|
||||
<span className='detailed-status__link'>
|
||||
<Icon id='star' />
|
||||
<span className='detailed-status__favorites'>
|
||||
<FormattedNumber value={status.get('favourites_count')} />
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={outerStyle}>
|
||||
<div ref={this.setRef} className={classNames('detailed-status', { compact })}>
|
||||
<NavLink to={`/${status.getIn(['account', 'acct'])}`} className='detailed-status__display-name'>
|
||||
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
|
||||
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
|
||||
</NavLink>
|
||||
|
||||
{(status.get('group') || status.get('revised_at') !== null) && (
|
||||
<div className='status__meta'>
|
||||
{status.get('group') && <React.Fragment>Posted in <NavLink to={`/groups/${status.getIn(['group', 'id'])}`}>{status.getIn(['group', 'title'])}</NavLink></React.Fragment>}
|
||||
{status.get('revised_at') !== null && <a onClick={this.handleShowRevisions}> Edited</a>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
|
||||
|
||||
{media}
|
||||
|
||||
{ /* status.get('quote') && <StatusQuote
|
||||
id={status.get('quote')}
|
||||
/> */ }
|
||||
|
||||
<div className='detailed-status__meta'>
|
||||
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
|
||||
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
|
||||
</a>{applicationLink} · {reblogLink} · {favouriteLink}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
.detailed-status {
|
||||
background: lighten($ui-base-color, 4%);
|
||||
padding: 14px 10px;
|
||||
|
||||
&--flex {
|
||||
@include flex(space-between, flex-start, row, wrap);
|
||||
|
||||
.status__content,
|
||||
.detailed-status__meta {
|
||||
flex: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.status__content {
|
||||
@include text-sizing(19px, 400, 24px);
|
||||
|
||||
.emojione {
|
||||
margin: -1px 0 0;
|
||||
|
||||
@include size(24px);
|
||||
}
|
||||
|
||||
.status__content__spoiler-link {
|
||||
line-height: 24px;
|
||||
margin: -1px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.video-player {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
|
||||
&__meta {
|
||||
margin-top: 15px;
|
||||
color: $dark-text-color;
|
||||
|
||||
@include text-sizing(14px, 400, 18px);
|
||||
}
|
||||
|
||||
&__datetime {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&__favorites,
|
||||
&__reblogs {
|
||||
display: inline-block;
|
||||
margin-left: 6px;
|
||||
|
||||
@include text-sizing(12px, 500);
|
||||
}
|
||||
|
||||
&__display-name,
|
||||
&__datetime,
|
||||
&__application {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&__display-name {
|
||||
&:hover strong {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&__application,
|
||||
&__datetime {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&__display-name {
|
||||
color: $secondary-text-color;
|
||||
display: block;
|
||||
line-height: 24px;
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
|
||||
strong,
|
||||
span {
|
||||
display: block;
|
||||
|
||||
@include text-overflow;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-size: 16px;
|
||||
color: $primary-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__display-avatar {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './detailed_status'
|
@ -1,235 +0,0 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { openModal } from '../../../../actions/modal';
|
||||
import { me, isStaff } from '../../../../initial_state';
|
||||
import IconButton from '../../../../components/icon_button';
|
||||
|
||||
const messages = defineMessages({
|
||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
edit: { id: 'status.edit', defaultMessage: 'Edit' },
|
||||
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
||||
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
||||
reply: { id: 'status.reply', defaultMessage: 'Reply' },
|
||||
reblog: { id: 'status.reblog', defaultMessage: 'Repost' },
|
||||
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
||||
reblog_private: { id: 'status.reblog_private', defaultMessage: 'Repost to original audience' },
|
||||
cancel_reblog_private: { id: 'status.cancel_reblog_private', defaultMessage: 'Un-repost' },
|
||||
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be reposted' },
|
||||
cannot_quote: { id: 'status.cannot_quote', defaultMessage: 'This post cannot be quoted' },
|
||||
favourite: { id: 'status.favourite', defaultMessage: 'Favorite' },
|
||||
mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' },
|
||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||
block: { id: 'status.block', defaultMessage: 'Block @{name}' },
|
||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
||||
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
|
||||
embed: { id: 'status.embed', defaultMessage: 'Embed' },
|
||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
|
||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onOpenUnauthorizedModal() {
|
||||
dispatch(openModal('UNAUTHORIZED'));
|
||||
},
|
||||
});
|
||||
|
||||
export default
|
||||
@connect(null, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class ActionBar extends ImmutablePureComponent {
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
onReply: PropTypes.func.isRequired,
|
||||
onReblog: PropTypes.func.isRequired,
|
||||
onQuote: PropTypes.func.isRequired,
|
||||
onFavourite: PropTypes.func.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
onMention: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func,
|
||||
onMuteConversation: PropTypes.func,
|
||||
onBlock: PropTypes.func,
|
||||
onReport: PropTypes.func,
|
||||
onPin: PropTypes.func,
|
||||
onEmbed: PropTypes.func,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onOpenUnauthorizedModal: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
handleReplyClick = () => {
|
||||
if (me) {
|
||||
this.props.onReply(this.props.status);
|
||||
} else {
|
||||
this.props.onOpenUnauthorizedModal();
|
||||
}
|
||||
}
|
||||
|
||||
handleReblogClick = (e) => {
|
||||
if (me) {
|
||||
this.props.onReblog(this.props.status, e);
|
||||
} else {
|
||||
this.props.onOpenUnauthorizedModal();
|
||||
}
|
||||
}
|
||||
|
||||
handleQuoteClick = (e) => {
|
||||
if (me) {
|
||||
this.props.onQuote(this.props.status, e);
|
||||
} else {
|
||||
this.props.onOpenUnauthorizedModal();
|
||||
}
|
||||
}
|
||||
|
||||
handleFavouriteClick = () => {
|
||||
if (me) {
|
||||
this.props.onFavourite(this.props.status);
|
||||
} else {
|
||||
this.props.onOpenUnauthorizedModal();
|
||||
}
|
||||
}
|
||||
|
||||
handleDeleteClick = () => {
|
||||
this.props.onDelete(this.props.status, this.context.router.history);
|
||||
}
|
||||
|
||||
handleEditClick = () => {
|
||||
this.props.onEdit(this.props.status);
|
||||
}
|
||||
|
||||
handleMentionClick = () => {
|
||||
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
||||
}
|
||||
|
||||
handleMuteClick = () => {
|
||||
this.props.onMute(this.props.status.get('account'));
|
||||
}
|
||||
|
||||
handleConversationMuteClick = () => {
|
||||
this.props.onMuteConversation(this.props.status);
|
||||
}
|
||||
|
||||
handleBlockClick = () => {
|
||||
this.props.onBlock(this.props.status);
|
||||
}
|
||||
|
||||
handleReport = () => {
|
||||
this.props.onReport(this.props.status);
|
||||
}
|
||||
|
||||
handlePinClick = () => {
|
||||
this.props.onPin(this.props.status);
|
||||
}
|
||||
|
||||
handleShare = () => {
|
||||
navigator.share({
|
||||
text: this.props.status.get('search_index'),
|
||||
url: this.props.status.get('url'),
|
||||
});
|
||||
}
|
||||
|
||||
handleEmbed = () => {
|
||||
this.props.onEmbed(this.props.status);
|
||||
}
|
||||
|
||||
handleCopy = () => {
|
||||
const url = this.props.status.get('url');
|
||||
const textarea = document.createElement('textarea');
|
||||
|
||||
textarea.textContent = url;
|
||||
textarea.style.position = 'fixed';
|
||||
|
||||
document.body.appendChild(textarea);
|
||||
|
||||
try {
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
} catch (e) {
|
||||
|
||||
} finally {
|
||||
document.body.removeChild(textarea);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const { status, intl } = this.props;
|
||||
|
||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||
const mutingConversation = status.get('muted');
|
||||
|
||||
let menu = [];
|
||||
|
||||
if (publicStatus) {
|
||||
menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
|
||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
if (me === status.getIn(['account', 'id'])) {
|
||||
if (publicStatus) {
|
||||
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
} else {
|
||||
if (status.get('visibility') === 'private') {
|
||||
menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_reblog_private : messages.reblog_private), action: this.handleReblogClick });
|
||||
}
|
||||
}
|
||||
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
if (isStaff) {
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
}
|
||||
}
|
||||
|
||||
const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && (
|
||||
<div className='detailed-status-action-bar__button'><IconButton title={intl.formatMessage(messages.share)} icon='share-alt' onClick={this.handleShare} /></div>
|
||||
);
|
||||
|
||||
let replyIcon;
|
||||
if (status.get('in_reply_to_id', null) === null) {
|
||||
replyIcon = 'reply';
|
||||
} else {
|
||||
replyIcon = 'reply-all';
|
||||
}
|
||||
|
||||
let reblogIcon = 'retweet';
|
||||
if (status.get('visibility') === 'direct') reblogIcon = 'envelope';
|
||||
else if (status.get('visibility') === 'private') reblogIcon = 'lock';
|
||||
|
||||
let reblog_disabled = (status.get('visibility') === 'direct' || status.get('visibility') === 'private');
|
||||
|
||||
return (
|
||||
<div className='detailed-status__action-bar'>
|
||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton disabled={reblog_disabled} active={status.get('reblogged')} title={reblog_disabled ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton disabled={reblog_disabled} title={reblog_disabled ? intl.formatMessage(messages.cannot_quote) : intl.formatMessage(messages.quote)} icon='quote-left' onClick={this.handleQuoteClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
|
||||
{shareButton}
|
||||
|
||||
<div className='detailed-status-action-bar__dropdown'>
|
||||
<DropdownMenuContainer size={18} icon='ellipsis-h' items={menu} direction='left' title='More' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
.detailed-status-action-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 10px 0;
|
||||
background: lighten($ui-base-color, 4%);
|
||||
border-top: 1px solid lighten($ui-base-color, 8%);
|
||||
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||
|
||||
&__button {
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__dropdown {
|
||||
flex: 1 1 auto;
|
||||
position: relative;
|
||||
|
||||
@include flex(center, center);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './detailed_status_action_bar'
|
@ -467,7 +467,7 @@ class Status extends ImmutablePureComponent {
|
||||
|
||||
<HotKeys handlers={handlers}>
|
||||
<div className={classNames('focusable', 'detailed-status__wrapper')} tabIndex='0' aria-label={textForScreenReader(intl, status, false)}>
|
||||
<DetailedStatus
|
||||
{ /* <DetailedStatus
|
||||
status={status}
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
onOpenMedia={this.handleOpenMedia}
|
||||
@ -475,6 +475,12 @@ class Status extends ImmutablePureComponent {
|
||||
domain={domain}
|
||||
showMedia={this.state.showMedia}
|
||||
onToggleMediaVisibility={this.handleToggleMediaVisibility}
|
||||
/> */ }
|
||||
|
||||
<StatusContainer
|
||||
id={status.get('id')}
|
||||
contextType={'timelineId'}
|
||||
showThread
|
||||
/>
|
||||
|
||||
<ActionBar
|
||||
|
@ -30,38 +30,39 @@ import HomePage from '../../pages/home_page'
|
||||
import NotificationsPage from '../../pages/notifications_page'
|
||||
import ListPage from '../../pages/list_page'
|
||||
import ListsPage from '../../pages/lists_page'
|
||||
import BasicPage from '../../pages/basic_page'
|
||||
import SettingsPage from '../../pages/settings_page'
|
||||
// import GroupSidebarPanel from '../groups/sidebar_panel'
|
||||
|
||||
import {
|
||||
Status,
|
||||
// GettingStarted,
|
||||
CommunityTimeline,
|
||||
AccountGallery,
|
||||
AccountTimeline,
|
||||
// AccountGallery,
|
||||
HomeTimeline,
|
||||
Blocks,
|
||||
CommunityTimeline,
|
||||
DomainBlocks,
|
||||
Explore,
|
||||
Favorites,
|
||||
FavoritedStatuses,
|
||||
Followers,
|
||||
Following,
|
||||
// Reblogs,
|
||||
// DirectTimeline,
|
||||
// HashtagTimeline,
|
||||
Notifications,
|
||||
// FollowRequests,
|
||||
FollowRequests,
|
||||
GenericNotFound,
|
||||
FavoritedStatuses,
|
||||
// Blocks,
|
||||
// DomainBlocks,
|
||||
// Mutes,
|
||||
Search,
|
||||
// Explore,
|
||||
GettingStarted,
|
||||
GroupsCollection,
|
||||
GroupTimeline,
|
||||
ListTimeline,
|
||||
ListsDirectory,
|
||||
GroupMembers,
|
||||
GroupRemovedAccounts,
|
||||
GroupCreate,
|
||||
GroupEdit,
|
||||
GroupMembers,
|
||||
GroupRemovedAccounts,
|
||||
GroupTimeline,
|
||||
HashtagTimeline,
|
||||
HomeTimeline,
|
||||
ListsDirectory,
|
||||
ListTimeline,
|
||||
Mutes,
|
||||
Notifications,
|
||||
Reblogs,
|
||||
Search,
|
||||
Status,
|
||||
} from './util/async-components'
|
||||
import { me, meUsername } from '../../initial_state'
|
||||
|
||||
@ -86,7 +87,6 @@ const keyMap = {
|
||||
new: 'n',
|
||||
search: 's',
|
||||
forceNew: 'option+n',
|
||||
focusColumn: ['1', '2', '3', '4', '5', '6', '7', '8', '9'],
|
||||
reply: 'r',
|
||||
Favorite: 'f',
|
||||
boost: 'b',
|
||||
@ -100,13 +100,10 @@ const keyMap = {
|
||||
goToNotifications: 'g n',
|
||||
goToStart: 'g s',
|
||||
goToFavorites: 'g f',
|
||||
goToPinned: 'g p',
|
||||
goToProfile: 'g u',
|
||||
goToBlocked: 'g b',
|
||||
goToMuted: 'g m',
|
||||
goToRequests: 'g r',
|
||||
toggleHidden: 'x',
|
||||
toggleSensitive: 'h',
|
||||
}
|
||||
|
||||
class SwitchingArea extends PureComponent {
|
||||
@ -146,7 +143,7 @@ class SwitchingArea extends PureComponent {
|
||||
<Redirect from='/' to='/home' exact />
|
||||
<WrappedRoute path='/home' exact page={HomePage} component={HomeTimeline} content={children} />
|
||||
|
||||
<WrappedRoute path='/timeline/all' exact page={HomePage} component={CommunityTimeline} content={children} />
|
||||
<WrappedRoute path='/timeline/all' exact page={BasicPage} component={CommunityTimeline} content={children} componentParams={{ title: 'Hashtag Timeline' }} />
|
||||
|
||||
<WrappedRoute path='/groups' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'featured' }} />
|
||||
<WrappedRoute path='/groups/browse/member' exact page={GroupsPage} component={GroupsCollection} content={children} componentParams={{ activeTab: 'member' }} />
|
||||
@ -158,7 +155,7 @@ class SwitchingArea extends PureComponent {
|
||||
<WrappedRoute path='/groups/:id/edit' page={GroupPage} component={GroupEdit} content={children} />
|
||||
<WrappedRoute path='/groups/:id' page={GroupPage} component={GroupTimeline} content={children} />
|
||||
|
||||
{ /* <WrappedRoute path='/tags/:id' publicRoute component={HashtagTimeline} content={children} /> */}
|
||||
<WrappedRoute path='/tags/:id' publicRoute page={BasicPage} component={HashtagTimeline} content={children} componentParams={{ title: 'Hashtag' }} />
|
||||
|
||||
<WrappedRoute path='/lists' exact page={ListsPage} component={ListsDirectory} content={children} />
|
||||
<WrappedRoute path='/list/:id' page={ListPage} component={ListTimeline} content={children} />
|
||||
@ -171,15 +168,15 @@ class SwitchingArea extends PureComponent {
|
||||
<WrappedRoute path='/search/groups' exact page={SearchPage} component={Search} content={children} />
|
||||
|
||||
{/*
|
||||
<WrappedRoute path='/settings/account' exact page={SettingsPage} component={Mutes} content={children} />
|
||||
<WrappedRoute path='/settings/profile' exact page={SettingsPage} component={Mutes} content={children} />
|
||||
<WrappedRoute path='/settings/account' exact page={SettingsPage} component={AccountSettings} content={children} />
|
||||
<WrappedRoute path='/settings/profile' exact page={SettingsPage} component={ProfileSettings} content={children} />
|
||||
<WrappedRoute path='/settings/domain_blocks' exact page={SettingsPage} component={DomainBlocks} content={children} />
|
||||
<WrappedRoute path='/settings/relationships' exact page={SettingsPage} component={DomainBlocks} content={children} />
|
||||
<WrappedRoute path='/settings/filters' exact page={SettingsPage} component={DomainBlocks} content={children} />
|
||||
<WrappedRoute path='/settings/relationships' exact page={SettingsPage} component={RelationshipSettings} content={children} />
|
||||
<WrappedRoute path='/settings/filters' exact page={SettingsPage} component={Filters} content={children} />
|
||||
<WrappedRoute path='/settings/blocks' exact page={SettingsPage} component={Blocks} content={children} />
|
||||
<WrappedRoute path='/settings/mutes' exact page={SettingsPage} component={Mutes} content={children} />
|
||||
<WrappedRoute path='/settings/development' exact page={SettingsPage} component={Mutes} content={children} />
|
||||
<WrappedRoute path='/settings/billing' exact page={SettingsPage} component={Mutes} content={children} />
|
||||
<WrappedRoute path='/settings/development' exact page={SettingsPage} component={Development} content={children} />
|
||||
<WrappedRoute path='/settings/billing' exact page={SettingsPage} component={Billing} content={children} />
|
||||
*/ }
|
||||
|
||||
<Redirect from='/@:username' to='/:username' exact />
|
||||
@ -193,22 +190,25 @@ class SwitchingArea extends PureComponent {
|
||||
|
||||
<Redirect from='/@:username/following' to='/:username/following' />
|
||||
<WrappedRoute path='/:username/following' page={ProfilePage} component={Following} content={children} />
|
||||
{ /*
|
||||
<Redirect from='/@:username/media' to='/:username/media' />
|
||||
<WrappedRoute path='/:username/media' component={AccountGallery} page={ProfilePage} content={children} />
|
||||
*/ }
|
||||
|
||||
<Redirect from='/@:username/photos' to='/:username/photos' />
|
||||
<WrappedRoute path='/:username/photos' page={ProfilePage} component={AccountGallery} content={children} componentParams={{ mediaType: 'photo' }} />
|
||||
|
||||
<Redirect from='/@:username/videos' to='/:username/videos' />
|
||||
<WrappedRoute path='/:username/videos' page={ProfilePage} component={AccountGallery} content={children} componentParams={{ mediaType: 'video' }} />
|
||||
|
||||
<Redirect from='/@:username/favorites' to='/:username/favorites' />
|
||||
<WrappedRoute path='/:username/favorites' page={ProfilePage} component={FavoritedStatuses} content={children} />
|
||||
|
||||
{ /*
|
||||
<Redirect from='/@:username/posts/:statusId' to='/:username/posts/:statusId' exact />
|
||||
<WrappedRoute path='/:username/posts/:statusId' publicRoute exact component={Status} content={children} />
|
||||
*/ }
|
||||
<WrappedRoute path='/:username/posts/:statusId' publicRoute exact page={BasicPage} component={Status} content={children} componentParams={{ title: 'Status' }} />
|
||||
|
||||
{ /*
|
||||
<Redirect from='/@:username/posts/:statusId/reblogs' to='/:username/posts/:statusId/reblogs' />
|
||||
<WrappedRoute path='/:username/posts/:statusId/reblogs' component={Reblogs} content={children} />
|
||||
*/}
|
||||
<WrappedRoute path='/:username/posts/:statusId/reblogs' page={BasicPage} component={Reblogs} content={children} componentParams={{ title: 'Reblogs' }} />
|
||||
|
||||
<Redirect from='/@:username/posts/:statusId/favorites' to='/:username/posts/:statusId/favorites' />
|
||||
<WrappedRoute path='/:username/posts/:statusId/favorites' page={BasicPage} component={Favorites} content={children} componentParams={{ title: 'Favorites' }} />
|
||||
|
||||
<WrappedRoute page={ErrorPage} component={GenericNotFound} content={children} />
|
||||
</Switch>
|
||||
)
|
||||
@ -273,7 +273,7 @@ class UI extends PureComponent {
|
||||
|
||||
if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files')) {
|
||||
this.setState({
|
||||
draggingOver: true
|
||||
draggingOver: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -417,24 +417,6 @@ class UI extends PureComponent {
|
||||
this.props.dispatch(resetCompose())
|
||||
}
|
||||
|
||||
handleHotkeyFocusColumn = e => {
|
||||
const index = (e.key * 1) + 1 // First child is drawer, skip that
|
||||
const column = this.node.querySelector(`.column:nth-child(${index})`)
|
||||
if (!column) return
|
||||
const container = column.querySelector('.scrollable')
|
||||
|
||||
if (container) {
|
||||
const status = container.querySelector('.focusable')
|
||||
|
||||
if (status) {
|
||||
if (container.scrollTop > status.offsetTop) {
|
||||
status.scrollIntoView(true)
|
||||
}
|
||||
status.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleHotkeyBack = () => {
|
||||
if (window.history && window.history.length === 1) {
|
||||
this.context.router.history.push('/home') // homehack
|
||||
@ -467,10 +449,6 @@ class UI extends PureComponent {
|
||||
this.context.router.history.push(`/${meUsername}/favorites`)
|
||||
}
|
||||
|
||||
handleHotkeyGoToPinned = () => {
|
||||
this.context.router.history.push(`/${meUsername}/pins`)
|
||||
}
|
||||
|
||||
handleHotkeyGoToProfile = () => {
|
||||
this.context.router.history.push(`/${meUsername}`)
|
||||
}
|
||||
@ -500,13 +478,11 @@ class UI extends PureComponent {
|
||||
new: this.handleHotkeyNew,
|
||||
search: this.handleHotkeySearch,
|
||||
forceNew: this.handleHotkeyForceNew,
|
||||
focusColumn: this.handleHotkeyFocusColumn,
|
||||
back: this.handleHotkeyBack,
|
||||
goToHome: this.handleHotkeyGoToHome,
|
||||
goToNotifications: this.handleHotkeyGoToNotifications,
|
||||
goToStart: this.handleHotkeyGoToStart,
|
||||
goToFavorites: this.handleHotkeyGoToFavorites,
|
||||
goToPinned: this.handleHotkeyGoToPinned,
|
||||
goToProfile: this.handleHotkeyGoToProfile,
|
||||
goToBlocked: this.handleHotkeyGoToBlocked,
|
||||
goToMuted: this.handleHotkeyGoToMuted,
|
||||
|
@ -1,63 +1,3 @@
|
||||
export function EmojiPicker() {
|
||||
return import(/* webpackChunkName: "emoji_picker" */'../../../components/emoji/emoji_picker')
|
||||
}
|
||||
|
||||
export function Compose() {
|
||||
return import(/* webpackChunkName: "features/compose" */'../../compose')
|
||||
}
|
||||
|
||||
export function Notifications() {
|
||||
return import(/* webpackChunkName: "features/notifications" */'../../notifications')
|
||||
}
|
||||
|
||||
export function HomeTimeline() {
|
||||
return import(/* webpackChunkName: "features/home_timeline" */'../../home_timeline')
|
||||
}
|
||||
|
||||
export function CommunityTimeline() {
|
||||
return import(/* webpackChunkName: "features/community_timeline" */'../../community_timeline')
|
||||
}
|
||||
|
||||
export function HashtagTimeline() {
|
||||
return import(/* webpackChunkName: "features/hashtag_timeline" */'../../hashtag_timeline')
|
||||
}
|
||||
|
||||
export function ListTimeline() {
|
||||
return import(/* webpackChunkName: "features/list_timeline" */'../../list_timeline')
|
||||
}
|
||||
|
||||
export function GroupTimeline() {
|
||||
return import(/* webpackChunkName: "features/group_timeline" */'../../group_timeline')
|
||||
}
|
||||
|
||||
export function GroupMembers() {
|
||||
return import(/* webpackChunkName: "features/group_members" */'../../group_members')
|
||||
}
|
||||
|
||||
export function GroupRemovedAccounts() {
|
||||
return import(/* webpackChunkName: "features/group_removed_accounts" */'../../group_removed_accounts')
|
||||
}
|
||||
|
||||
export function GroupCreate() {
|
||||
return import(/* webpackChunkName: "features/groups_create" */'../../group_create')
|
||||
}
|
||||
|
||||
export function GroupEdit() {
|
||||
return import(/* webpackChunkName: "features/groups/timeline" */'../../groups/edit')
|
||||
}
|
||||
|
||||
export function GroupsCollection() {
|
||||
return import(/* webpackChunkName: "features/groups_collection" */'../../g../../groups_collection')
|
||||
}
|
||||
|
||||
export function ListsDirectory() {
|
||||
return import(/* webpackChunkName: "features/lists_directory" */'../../lists_directory')
|
||||
}
|
||||
|
||||
export function Status() {
|
||||
return import(/* webpackChunkName: "features/status" */'../../status')
|
||||
}
|
||||
|
||||
export function AccountTimeline() {
|
||||
return import(/* webpackChunkName: "features/account_timeline" */'../../account_timeline')
|
||||
}
|
||||
@ -66,6 +6,30 @@ export function AccountGallery() {
|
||||
return import(/* webpackChunkName: "features/account_gallery" */'../../account_gallery')
|
||||
}
|
||||
|
||||
export function Blocks() {
|
||||
return import(/* webpackChunkName: "features/blocks" */'../../blocks')
|
||||
}
|
||||
|
||||
export function CommunityTimeline() {
|
||||
return import(/* webpackChunkName: "features/community_timeline" */'../../community_timeline')
|
||||
}
|
||||
|
||||
export function Compose() {
|
||||
return import(/* webpackChunkName: "features/compose" */'../../compose')
|
||||
}
|
||||
|
||||
export function DomainBlocks() {
|
||||
return import(/* webpackChunkName: "features/domain_blocks" */'../../domain_blocks')
|
||||
}
|
||||
|
||||
export function EmbedModal() {
|
||||
return import(/* webpackChunkName: "modals/embed_modal" */'../../../components/modal/embed_modal')
|
||||
}
|
||||
|
||||
export function EmojiPicker() {
|
||||
return import(/* webpackChunkName: "emoji_picker" */'../../../components/emoji/emoji_picker')
|
||||
}
|
||||
|
||||
export function Followers() {
|
||||
return import(/* webpackChunkName: "features/followers" */'../../followers')
|
||||
}
|
||||
@ -74,28 +38,68 @@ export function Following() {
|
||||
return import(/* webpackChunkName: "features/following" */'../../following')
|
||||
}
|
||||
|
||||
export function Reblogs() {
|
||||
return import(/* webpackChunkName: "features/reblogs" */'../../reblogs')
|
||||
}
|
||||
|
||||
export function FollowRequests() {
|
||||
return import(/* webpackChunkName: "features/follow_requests" */'../../follow_requests')
|
||||
}
|
||||
|
||||
export function GenericNotFound() {
|
||||
return import(/* webpackChunkName: "features/generic_not_found" */'../../generic_not_found')
|
||||
}
|
||||
|
||||
export function FavoritedStatuses() {
|
||||
return import(/* webpackChunkName: "features/favorited_statuses" */'../../favorited_statuses')
|
||||
}
|
||||
|
||||
export function Blocks() {
|
||||
return import(/* webpackChunkName: "features/blocks" */'../../blocks')
|
||||
export function GenericNotFound() {
|
||||
return import(/* webpackChunkName: "features/generic_not_found" */'../../generic_not_found')
|
||||
}
|
||||
|
||||
export function DomainBlocks() {
|
||||
return import(/* webpackChunkName: "features/domain_blocks" */'../../domain_blocks')
|
||||
export function GroupsCollection() {
|
||||
return import(/* webpackChunkName: "features/groups_collection" */'../../g../../groups_collection')
|
||||
}
|
||||
|
||||
export function GroupCreate() {
|
||||
return import(/* webpackChunkName: "features/groups_create" */'../../group_create')
|
||||
}
|
||||
|
||||
export function GroupEdit() {
|
||||
return import(/* webpackChunkName: "features/groups/timeline" */'../../groups/edit')
|
||||
}
|
||||
|
||||
export function GroupMembers() {
|
||||
return import(/* webpackChunkName: "features/group_members" */'../../group_members')
|
||||
}
|
||||
|
||||
export function GroupRemovedAccounts() {
|
||||
return import(/* webpackChunkName: "features/group_removed_accounts" */'../../group_removed_accounts')
|
||||
}
|
||||
|
||||
export function GroupTimeline() {
|
||||
return import(/* webpackChunkName: "features/group_timeline" */'../../group_timeline')
|
||||
}
|
||||
|
||||
export function HashtagTimeline() {
|
||||
return import(/* webpackChunkName: "features/hashtag_timeline" */'../../hashtag_timeline')
|
||||
}
|
||||
|
||||
export function HomeTimeline() {
|
||||
return import(/* webpackChunkName: "features/home_timeline" */'../../home_timeline')
|
||||
}
|
||||
|
||||
export function ListAdder() {
|
||||
return import(/*webpackChunkName: "features/list_adder" */'../../list_adder')
|
||||
}
|
||||
|
||||
export function ListsDirectory() {
|
||||
return import(/* webpackChunkName: "features/lists_directory" */'../../lists_directory')
|
||||
}
|
||||
|
||||
export function ListEditor() {
|
||||
return import(/* webpackChunkName: "features/list_editor" */'../../list_editor')
|
||||
}
|
||||
|
||||
export function ListTimeline() {
|
||||
return import(/* webpackChunkName: "features/list_timeline" */'../../list_timeline')
|
||||
}
|
||||
|
||||
export function MediaGallery() {
|
||||
return import(/* webpackChunkName: "status/media_gallery" */'../../../components/media_gallery')
|
||||
}
|
||||
|
||||
export function Mutes() {
|
||||
@ -106,34 +110,30 @@ export function MuteModal() {
|
||||
return import(/* webpackChunkName: "modals/mute_modal" */'../../../components/modal/mute_modal')
|
||||
}
|
||||
|
||||
export function StatusRevisionModal() {
|
||||
return import(/* webpackChunkName: "modals/mute_modal" */'../../../components/modal/status_revision_modal')
|
||||
export function Notifications() {
|
||||
return import(/* webpackChunkName: "features/notifications" */'../../notifications')
|
||||
}
|
||||
|
||||
export function Reblogs() {
|
||||
return import(/* webpackChunkName: "features/reblogs" */'../../reblogs')
|
||||
}
|
||||
|
||||
export function ReportModal() {
|
||||
return import(/* webpackChunkName: "modals/report_modal" */'../../../components/modal/report_modal')
|
||||
}
|
||||
|
||||
export function MediaGallery() {
|
||||
return import(/* webpackChunkName: "status/media_gallery" */'../../../components/media_gallery')
|
||||
export function Search() {
|
||||
return import(/*webpackChunkName: "features/search" */'../../search')
|
||||
}
|
||||
|
||||
export function Status() {
|
||||
return import(/* webpackChunkName: "features/status" */'../../status')
|
||||
}
|
||||
|
||||
export function StatusRevisionModal() {
|
||||
return import(/* webpackChunkName: "modals/mute_modal" */'../../../components/modal/status_revision_modal')
|
||||
}
|
||||
|
||||
export function Video() {
|
||||
return import(/* webpackChunkName: "features/video" */'../../video')
|
||||
}
|
||||
|
||||
export function EmbedModal() {
|
||||
return import(/* webpackChunkName: "modals/embed_modal" */'../../../components/modal/embed_modal')
|
||||
}
|
||||
|
||||
export function ListEditor() {
|
||||
return import(/* webpackChunkName: "features/list_editor" */'../../list_editor')
|
||||
}
|
||||
|
||||
export function ListAdder() {
|
||||
return import(/*webpackChunkName: "features/list_adder" */'../../list_adder')
|
||||
}
|
||||
|
||||
export function Search() {
|
||||
return import(/*webpackChunkName: "features/search" */'../../search')
|
||||
}
|
||||
|
@ -19,13 +19,13 @@ export default class DefaultLayout extends PureComponent {
|
||||
// const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <button key='floating-action-button' onClick={this.handleOpenComposeModal} className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}></button>;
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundcolorSecondary3].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
|
||||
|
||||
<Sidebar />
|
||||
|
||||
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1, _s.borderColorSecondary2, _s.borderLeft1PX].join(' ')}>
|
||||
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundcolorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundColorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.paddingLeft15PX, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
|
||||
<div className={[_s.default, _s.width645PX].join(' ')}>
|
||||
<ColumnHeader
|
||||
|
@ -44,13 +44,13 @@ export default class GroupLayout extends ImmutablePureComponent {
|
||||
// const !!relationships && relationships.get('member')
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundcolorSecondary3].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
|
||||
|
||||
<Sidebar />
|
||||
|
||||
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1, _s.borderColorSecondary2, _s.borderLeft1PX].join(' ')}>
|
||||
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundcolorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundColorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.paddingLeft15PX, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
|
||||
<div className={[_s.default, _s.width645PX].join(' ')}>
|
||||
<ColumnHeader
|
||||
|
@ -43,7 +43,7 @@ export default class ProfileLayout extends ImmutablePureComponent {
|
||||
]
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundcolorSecondary3].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
|
||||
|
||||
<Sidebar />
|
||||
|
||||
|
@ -18,13 +18,13 @@ export default class SearchLayout extends PureComponent {
|
||||
// const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <button key='floating-action-button' onClick={this.handleOpenComposeModal} className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}></button>;
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundcolorSecondary3].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.width100PC, _s.heightMin100VH, _s.backgroundColorSecondary3].join(' ')}>
|
||||
|
||||
<Sidebar />
|
||||
|
||||
<main role='main' className={[_s.default, _s.flexShrink1, _s.flexGrow1, _s.borderColorSecondary2, _s.borderLeft1PX].join(' ')}>
|
||||
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundcolorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.borderBottom1PX, _s.borderColorSecondary2, _s.backgroundColorSecondary3, _s.z3, _s.top0, _s.positionFixed].join(' ')}>
|
||||
<div className={[_s.default, _s.height53PX, _s.paddingLeft15PX, _s.width1015PX, _s.flexRow, _s.justifyContentSpaceBetween].join(' ')}>
|
||||
<div className={[_s.default, _s.width645PX].join(' ')}>
|
||||
<ColumnHeader
|
||||
|
@ -10,6 +10,7 @@ const perf = require('./performance');
|
||||
function main() {
|
||||
perf.start('main()');
|
||||
|
||||
// : todo :
|
||||
// if (window.history && history.replaceState) {
|
||||
// const { pathname, search, hash } = window.location;
|
||||
// const path = pathname + search + hash;
|
||||
|
32
app/javascript/gabsocial/pages/basic_page.js
Normal file
@ -0,0 +1,32 @@
|
||||
import { Fragment } from 'react'
|
||||
import LinkFooter from '../components/link_footer'
|
||||
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
|
||||
import TrendsPanel from '../components/panel/trends_panel'
|
||||
import DefaultLayout from '../layouts/default_layout'
|
||||
|
||||
export default class BasicPage extends PureComponent {
|
||||
static propTypes = {
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, title } = this.props
|
||||
|
||||
return (
|
||||
<DefaultLayout
|
||||
title={title}
|
||||
layout={(
|
||||
<Fragment>
|
||||
<TrendsPanel />
|
||||
<WhoToFollowPanel />
|
||||
<LinkFooter />
|
||||
</Fragment>
|
||||
)}
|
||||
showBackBtn
|
||||
>
|
||||
{children}
|
||||
</DefaultLayout>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Fragment } from 'react'
|
||||
import LinkFooter from '../components/link_footer'
|
||||
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
|
||||
import NotificationFilterPanel from '../components/panel/notification_filter_panel'
|
||||
import TrendsPanel from '../components/panel/trends_panel'
|
||||
import DefaultLayout from '../layouts/default_layout'
|
||||
|
||||
@ -13,6 +14,7 @@ export default class NotificationsPage extends PureComponent {
|
||||
title='Notifications'
|
||||
layout={(
|
||||
<Fragment>
|
||||
<NotificationFilterPanel />
|
||||
<TrendsPanel />
|
||||
<WhoToFollowPanel />
|
||||
<LinkFooter />
|
||||
|
@ -59,10 +59,14 @@ const normalizeNotification = (state, notification) => {
|
||||
const expandNormalizedNotifications = (state, notifications, next) => {
|
||||
let items = ImmutableList();
|
||||
|
||||
// : todo filter notiications here:
|
||||
|
||||
notifications.forEach((n, i) => {
|
||||
items = items.set(i, notificationToMap(n));
|
||||
});
|
||||
|
||||
console.log("reducer notifications:", notifications)
|
||||
|
||||
return state.withMutations(mutable => {
|
||||
if (!items.isEmpty()) {
|
||||
mutable.update('items', list => {
|
||||
@ -74,7 +78,9 @@ const expandNormalizedNotifications = (state, notifications, next) => {
|
||||
item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
|
||||
);
|
||||
|
||||
return list.take(firstIndex).concat(items, list.skip(lastIndex));
|
||||
const pop = list.take(firstIndex).concat(items, list.skip(lastIndex));
|
||||
console.log("pop:", pop)
|
||||
return pop
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="2048" height="1792" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1344 1504q0 13-9.5 22.5t-22.5 9.5h-960q-8 0-13.5-2t-9-7-5.5-8-3-11.5-1-11.5v-600h-192q-26 0-45-19t-19-45q0-24 15-41l320-384q19-22 49-22t49 22l320 384q15 17 15 41 0 26-19 45t-45 19h-192v384h576q16 0 25 11l160 192q7 10 7 21zm640-416q0 24-15 41l-320 384q-20 23-49 23t-49-23l-320-384q-15-17-15-41 0-26 19-45t45-19h192v-384h-576q-16 0-25-12l-160-192q-7-9-7-20 0-13 9.5-22.5t22.5-9.5h960q8 0 13.5 2t9 7 5.5 8 3 11.5 1 11.5v600h192q26 0 45 19t19 45z" fill="#fff"/></svg>
|
Before Width: | Height: | Size: 604 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 214 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 273 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 205 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M14.4 6L14 4H5v17h2v-7h5.6l.4 2h7V6z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 197 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 252 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 395 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 305 B |
@ -1,4 +0,0 @@
|
||||
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 220 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.41507 232.00976"><path d="M211.80683 139.0875c-3.1825 16.36625-28.4925 34.2775-57.5625 37.74875-15.16 1.80875-30.0825 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.3925 27.9425 21.115.7225 39.91625-5.20625 39.91625-5.20625l.86875 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23183 213.82 1.40558 165.31125.20808 116.09125c-.36375-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67058 3.45375 78.20308.2425 107.86433 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.97625 14.7525 32.97625 65.0825 0 0 .4125 37.13375-4.6 62.915" fill="#3088d4"/><path d="M65.68743 96.45938c0 9.01375-7.3075 16.32125-16.3225 16.32125-9.01375 0-16.32-7.3075-16.32-16.32125 0-9.01375 7.30625-16.3225 16.32-16.3225 9.015 0 16.3225 7.30875 16.3225 16.3225M124.52893 96.45938c0 9.01375-7.30875 16.32125-16.3225 16.32125-9.01375 0-16.32125-7.3075-16.32125-16.32125 0-9.01375 7.3075-16.3225 16.32125-16.3225 9.01375 0 16.3225 7.30875 16.3225 16.3225M183.36933 96.45938c0 9.01375-7.3075 16.32125-16.32125 16.32125-9.01375 0-16.32125-7.3075-16.32125-16.32125 0-9.01375 7.3075-16.3225 16.32125-16.3225 9.01375 0 16.32125 7.30875 16.32125 16.3225" fill="#fff"/></svg>
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 15 KiB |
@ -1,27 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import loadPolyfills from '../gabsocial/load_polyfills';
|
||||
import { start } from '../gabsocial/common';
|
||||
|
||||
start();
|
||||
|
||||
function loaded() {
|
||||
const TimelineContainer = require('../gabsocial/containers/timeline_container').default;
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const mountNode = document.getElementById('gabsocial-timeline');
|
||||
|
||||
if (mountNode !== null) {
|
||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
||||
ReactDOM.render(<TimelineContainer {...props} />, mountNode);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const ready = require('../gabsocial/ready').default;
|
||||
ready(loaded);
|
||||
}
|
||||
|
||||
loadPolyfills().then(main).catch(error => {
|
||||
console.error(error);
|
||||
});
|
@ -1 +1 @@
|
||||
//
|
||||
// : todo :
|
||||
|
@ -1,27 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import loadPolyfills from '../gabsocial/load_polyfills';
|
||||
import { start } from '../gabsocial/common';
|
||||
|
||||
start();
|
||||
|
||||
function loaded() {
|
||||
const ComposeContainer = require('../gabsocial/containers/compose_container').default;
|
||||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const mountNode = document.getElementById('gabsocial-compose');
|
||||
|
||||
if (mountNode !== null) {
|
||||
const props = JSON.parse(mountNode.getAttribute('data-props'));
|
||||
ReactDOM.render(<ComposeContainer {...props} />, mountNode);
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
const ready = require('../gabsocial/ready').default;
|
||||
ready(loaded);
|
||||
}
|
||||
|
||||
loadPolyfills().then(main).catch(error => {
|
||||
console.error(error);
|
||||
});
|
@ -1,3 +0,0 @@
|
||||
$font-sans-serif: 'gabsocial-font-sans-serif' !default;
|
||||
$font-display: 'gabsocial-font-display' !default;
|
||||
$font-monospace: 'gabsocial-font-monospace' !default;
|
@ -1,318 +0,0 @@
|
||||
@mixin breakpoint($point) {
|
||||
@if $point==lg {
|
||||
@media screen and (min-width: 1366px) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@else if $point==md {
|
||||
@media screen and (min-width: 1024px) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@else if $point==sm {
|
||||
@media screen and (max-width: 600px) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin theme($themes: $themes) {
|
||||
|
||||
@each $theme,
|
||||
$map in $themes {
|
||||
.theme-#{$theme} & {
|
||||
$theme-map: () !global;
|
||||
|
||||
@each $key,
|
||||
$submap in $map {
|
||||
$value: map-get(map-get($themes, $theme), '#{$key}');
|
||||
$theme-map: map-merge($theme-map, ($key: $value)) !global;
|
||||
}
|
||||
|
||||
@content;
|
||||
$theme-map: null !global;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin margin-center($vertical: 0) {
|
||||
@if ($vertical !=0) {
|
||||
margin: $vertical auto $vertical auto;
|
||||
}
|
||||
|
||||
@else {
|
||||
margin: {
|
||||
left: auto;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin horizontal-margin($left, $right: $left) {
|
||||
margin-left: $left;
|
||||
margin-right: $right;
|
||||
}
|
||||
|
||||
@mixin vertical-margin($top, $bottom: $top) {
|
||||
margin-top: $top;
|
||||
margin-bottom: $bottom;
|
||||
}
|
||||
|
||||
@mixin horizontal-padding($left, $right: $left) {
|
||||
padding-left: $left;
|
||||
padding-right: $right;
|
||||
}
|
||||
|
||||
@mixin vertical-padding($top, $bottom: $top) {
|
||||
padding-top: $top;
|
||||
padding-bottom: $bottom;
|
||||
}
|
||||
|
||||
@function z($name) {
|
||||
@if index($z-indexes, $name) {
|
||||
@return (length($z-indexes) - index($z-indexes, $name))+1;
|
||||
}
|
||||
|
||||
@else {
|
||||
@warn 'There is no item "#{$name}" in this list; choose one of: #{$z-indexes}';
|
||||
@return null;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin flex($justifyContent: flex-start, $alignItems: stretch, $direction: row, $flexWrap: nowrap) {
|
||||
display: flex;
|
||||
|
||||
@if ($justifyContent) {
|
||||
justify-content: $justifyContent;
|
||||
}
|
||||
|
||||
@if ($alignItems) {
|
||||
align-items: $alignItems;
|
||||
}
|
||||
|
||||
@if ($direction) {
|
||||
flex-direction: $direction;
|
||||
}
|
||||
|
||||
@if ($flexWrap) {
|
||||
flex-wrap: $flexWrap;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin abs-position($top: auto, $right: auto, $bottom: auto, $left: auto, $includeAbsolute:true) {
|
||||
@if ($includeAbsolute) {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
top: $top;
|
||||
left: $left;
|
||||
bottom: $bottom;
|
||||
right: $right;
|
||||
}
|
||||
|
||||
@mixin border-design($color: #fff, $size: 1px, $radius: 0px) {
|
||||
border-radius: $radius;
|
||||
border: $size solid $color;
|
||||
}
|
||||
|
||||
@mixin bottom-spacing($margin: 0px, $padding: $margin) {
|
||||
margin-bottom: $margin;
|
||||
padding-bottom: $padding;
|
||||
}
|
||||
|
||||
@mixin text-sizing($fontSize, $fontWeight, $lineHeight: 1, $textAlign: '', $letterSpacing: '') {
|
||||
font-size: $fontSize;
|
||||
font-weight: $fontWeight;
|
||||
|
||||
@if ($lineHeight !=1) {
|
||||
line-height: $lineHeight;
|
||||
}
|
||||
|
||||
@if ($textAlign !='') {
|
||||
text-align: $textAlign;
|
||||
}
|
||||
|
||||
@if ($letterSpacing !='') {
|
||||
letter-spacing: $letterSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin background-image($url: "", $size: cover, $position: center, $repeat: no-repeat) {
|
||||
@if ($url !="") {
|
||||
background-image: url($url);
|
||||
}
|
||||
|
||||
background-size: $size;
|
||||
background-position: $position;
|
||||
background-repeat: $repeat;
|
||||
}
|
||||
|
||||
@mixin pseudo($content: "", $display: block, $position: absolute) {
|
||||
content: $content;
|
||||
display: $display;
|
||||
position: $position;
|
||||
}
|
||||
|
||||
@mixin circle($size) {
|
||||
@include size($size);
|
||||
border-radius: $size / 2;
|
||||
}
|
||||
|
||||
@mixin size($width: 100%, $height: $width) {
|
||||
width: $width;
|
||||
height: $height;
|
||||
}
|
||||
|
||||
@mixin min-size($width: 100%, $height: $width) {
|
||||
min-width: $width;
|
||||
min-height: $height;
|
||||
}
|
||||
|
||||
@mixin max-size($width: 100%, $height: $width) {
|
||||
max-width: $width;
|
||||
max-height: $height;
|
||||
}
|
||||
|
||||
@mixin unselectable {
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@mixin text-overflow($whitespace: '', $wordWrap: '') {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@if ($whitespace !='') {
|
||||
white-space: $whitespace;
|
||||
}
|
||||
|
||||
@if ($wordWrap !='') {
|
||||
word-wrap: $wordWrap;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin input-placeholder {
|
||||
&.placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&:-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&::-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&:-ms-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&::-webkit-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// standard container drop shadow
|
||||
@mixin light-theme-shadow() {
|
||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// common properties for all standard containers
|
||||
@mixin gab-container-standards() {
|
||||
border-radius: 10px;
|
||||
background: $gab-background-container;
|
||||
|
||||
body.theme-gabsocial-light & {
|
||||
@include light-theme-shadow();
|
||||
background: $gab-background-container-light;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin avatar-radius() {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@mixin search-input() {
|
||||
outline: 0;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
box-shadow: none;
|
||||
font-family: inherit;
|
||||
background: $gab-background-container;
|
||||
color: $gab-text-highlight;
|
||||
margin: 0;
|
||||
|
||||
@include text-sizing(16px, 400, 19px);
|
||||
@include border-design($gab-placeholder-accent, 1px, 4px);
|
||||
|
||||
@include input-placeholder {
|
||||
color: $gab-placeholder-accent;
|
||||
}
|
||||
|
||||
&::-moz-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&::-moz-focus-inner,
|
||||
&:focus,
|
||||
&:active {
|
||||
outline: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// TYPEOGRAPHY MIXINS
|
||||
|
||||
// declare the font family using these shortcuts
|
||||
@mixin font-roboto() {
|
||||
font-family: 'Roboto', Arial, sans-serif !important;
|
||||
}
|
||||
|
||||
@mixin font-montserrat() {
|
||||
font-family: 'Montserrat', Arial, sans-serif !important;
|
||||
}
|
||||
|
||||
// Declare font weights as a numerical value in rendered output
|
||||
// Prevents certain browsers which do not play nice with "light, medium" textual declarations
|
||||
// Numeical values always work more consistently across browsers
|
||||
// Each font-weight is linked with the @font-face declaration to the actual font file
|
||||
@mixin font-weight($weight) {
|
||||
@if $weight=='light' {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@if $weight=='normal' {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@if $weight=='medium' {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@if $weight=='bold' {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@if $weight=='extrabold' {
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
||||
|
||||
// Use these mixins to define font-size and line-height
|
||||
// html and body declaration allows developer to pass px value as argument
|
||||
// Rendered css will default to "rem" and fall back to "px" for unsupported browsers
|
||||
@mixin font-size($size) {
|
||||
$rem: ($size / 10);
|
||||
$px: $size;
|
||||
font-size: #{$px + "px"};
|
||||
font-size: #{$rem + "rem"};
|
||||
}
|
||||
|
||||
@mixin line-height($size) {
|
||||
$rem: ($size / 10);
|
||||
$px: $size;
|
||||
line-height: #{$px + "px"};
|
||||
line-height: #{$rem + "rem"};
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
// todo
|
||||
$themes: (
|
||||
light: (
|
||||
backgroundColor: #fff,
|
||||
),
|
||||
dark: (
|
||||
backgroundColor: #fff,
|
||||
),
|
||||
contrast: (
|
||||
backgroundColor: #fff,
|
||||
),
|
||||
);
|
@ -1,31 +0,0 @@
|
||||
// turns navigation links into icon-only buttons
|
||||
$nav-breakpoint-1: 850px;
|
||||
// search field hidden and replaced with search icon link
|
||||
$nav-breakpoint-2: 650px;
|
||||
// "Gab" button hidden and replaced with floating button on bottom corner
|
||||
$nav-breakpoint-3: 450px;
|
||||
// Gab Logo hidden - bare minimum navigation for smallest width devices
|
||||
$nav-breakpoint-4: 375px;
|
||||
|
||||
$no-gap-breakpoint: 415px;
|
||||
|
||||
// Variables for components
|
||||
$media-modal-media-max-width: 100%;
|
||||
// put margins on top and bottom of image to avoid the screen covered by image.
|
||||
$media-modal-media-max-height: 80%;
|
||||
|
||||
$z-indexes: (
|
||||
'outdated-browser',
|
||||
'page-wrapper',
|
||||
'site-header',
|
||||
'site-footer'
|
||||
'modal-backdrop',
|
||||
'modal',
|
||||
);
|
||||
|
||||
// Language codes that uses CJK fonts
|
||||
$cjk-langs: ja,
|
||||
ko,
|
||||
zh-CN,
|
||||
zh-HK,
|
||||
zh-TW;
|
@ -15,23 +15,6 @@
|
||||
// NOTE - In the process of stripping this giant file into individual components (below)
|
||||
@import 'gabsocial/components';
|
||||
|
||||
// COMPONENTS
|
||||
@import 'gabsocial/components/inputs';
|
||||
@import 'gabsocial/components/tabs-bar';
|
||||
@import 'gabsocial/components/dropdown-menu';
|
||||
@import 'gabsocial/components/modal';
|
||||
@import 'gabsocial/components/account-header';
|
||||
@import 'gabsocial/components/user-panel';
|
||||
@import 'gabsocial/components/compose-form';
|
||||
@import 'gabsocial/components/group-card';
|
||||
@import 'gabsocial/components/group-detail';
|
||||
@import 'gabsocial/components/group-accounts';
|
||||
@import 'gabsocial/components/group-form';
|
||||
@import 'gabsocial/components/group-sidebar-panel';
|
||||
@import 'gabsocial/components/sidebar-menu';
|
||||
@import 'gabsocial/components/status-revisions';
|
||||
@import 'gabsocial/components/footer-bar';
|
||||
|
||||
@import 'gabsocial/polls';
|
||||
@import 'gabsocial/emoji_picker';
|
||||
@import 'gabsocial/about';
|
||||
|
@ -1,5 +1,3 @@
|
||||
@import './variables';
|
||||
@import './colors';
|
||||
@import './themes';
|
||||
@import './font_families';
|
||||
@import './mixins';
|
@ -1,67 +0,0 @@
|
||||
// components.scss
|
||||
.compose-form {
|
||||
.compose-form__modifiers {
|
||||
.compose-form__upload {
|
||||
&-description {
|
||||
input {
|
||||
&::placeholder {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rich-formatting a,
|
||||
.rich-formatting p a,
|
||||
.rich-formatting li a,
|
||||
.landing-page__short-description p a,
|
||||
.status__content a,
|
||||
.reply-indicator__content a {
|
||||
color: lighten($ui-highlight-color, 12%);
|
||||
text-decoration: underline;
|
||||
|
||||
&.mention {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.mention span {
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.status__content__spoiler-link {
|
||||
color: $secondary-text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.status__content__read-more-button {
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.nothing-here {
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
.public-layout .public-account-header__tabs__tabs .counter.active::after {
|
||||
border-bottom: 4px solid $ui-highlight-color;
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Dependent colors
|
||||
$black: #000000;
|
||||
|
||||
$classic-base-color: #282c37;
|
||||
$classic-primary-color: #9baec8;
|
||||
$classic-secondary-color: #d9e1e8;
|
||||
$classic-highlight-color: #2b90d9;
|
||||
|
||||
$ui-base-color: $classic-base-color !default;
|
||||
$ui-primary-color: $classic-primary-color !default;
|
||||
$ui-secondary-color: $classic-secondary-color !default;
|
||||
|
||||
// Differences
|
||||
$ui-highlight-color: #2b5fd9;
|
||||
|
||||
$darker-text-color: lighten($ui-primary-color, 20%) !default;
|
||||
$dark-text-color: lighten($ui-primary-color, 12%) !default;
|
||||
$secondary-text-color: lighten($ui-secondary-color, 6%) !default;
|
||||
$highlight-text-color: $classic-highlight-color !default;
|
||||
$action-button-color: #8d9ac2;
|
||||
|
||||
$inverted-text-color: $black !default;
|
||||
$lighter-text-color: darken($ui-base-color,6%) !default;
|
||||
$light-text-color: darken($ui-primary-color, 40%) !default;
|
@ -1,329 +0,0 @@
|
||||
// Notes!
|
||||
// Sass color functions, "darken" and "lighten" are automatically replaced.
|
||||
|
||||
// Change the colors of button texts
|
||||
.button {
|
||||
color: $white;
|
||||
|
||||
&.button--alternative-2 {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// Change default background colors of columns
|
||||
.column {
|
||||
article {
|
||||
background: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer__inner {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
.drawer__inner__gabsocial {
|
||||
background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($white)}"/></svg>') no-repeat bottom / 100% auto;
|
||||
}
|
||||
|
||||
// Change the colors used in compose-form
|
||||
.compose-form {
|
||||
.compose-form__modifiers {
|
||||
.compose-form__upload-description input {
|
||||
color: lighten($white, 7%);
|
||||
&::placeholder {color: lighten($white, 7%);}
|
||||
}
|
||||
}
|
||||
|
||||
.compose-form__buttons-wrapper {
|
||||
background: darken($ui-base-color, 6%);
|
||||
}
|
||||
|
||||
.autosuggest-textarea__suggestions {
|
||||
background: darken($ui-base-color, 6%);
|
||||
}
|
||||
|
||||
.autosuggest-textarea__suggestions__item {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active,
|
||||
&.selected {
|
||||
background: lighten($ui-base-color, 4%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-mart-bar {
|
||||
border-color: lighten($ui-base-color, 4%);
|
||||
|
||||
&:first-child {
|
||||
background: darken($ui-base-color, 6%);
|
||||
}
|
||||
}
|
||||
|
||||
.emoji-mart-search input {
|
||||
background: rgba($ui-base-color, 0.3);
|
||||
border-color: $ui-base-color;
|
||||
}
|
||||
|
||||
// Change the background colors of statuses
|
||||
.focusable:focus {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
.status.status-direct {
|
||||
background: lighten($ui-base-color, 4%);
|
||||
}
|
||||
|
||||
.focusable:focus .status.status-direct {
|
||||
background: lighten($ui-base-color, 8%);
|
||||
}
|
||||
|
||||
.detailed-status,
|
||||
.detailed-status-action-bar {
|
||||
background: darken($ui-base-color, 6%);
|
||||
}
|
||||
|
||||
// Change the background colors of status__content__spoiler-link
|
||||
.reply-indicator__content .status__content__spoiler-link,
|
||||
.status__content .status__content__spoiler-link {
|
||||
background: $ui-base-lighter-color;
|
||||
|
||||
&:hover {
|
||||
background: lighten($ui-base-lighter-color, 6%);
|
||||
}
|
||||
}
|
||||
|
||||
// Change the background colors of media and video spoilers
|
||||
.media-spoiler,
|
||||
.video-player__spoiler {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
.account-gallery__item a {
|
||||
background-color: $ui-base-color;
|
||||
}
|
||||
|
||||
// Change the colors used in the dropdown menu
|
||||
.dropdown-menu {
|
||||
background: $ui-base-color;
|
||||
|
||||
&__arrow {
|
||||
&.left {
|
||||
border-left-color: $ui-base-color;
|
||||
}
|
||||
|
||||
&.top {
|
||||
border-top-color: $ui-base-color;
|
||||
}
|
||||
|
||||
&.bottom {
|
||||
border-bottom-color: $ui-base-color;
|
||||
}
|
||||
|
||||
&.right {
|
||||
border-right-color: $ui-base-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
a {
|
||||
background: $ui-base-color;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change the text colors on inverted background
|
||||
.privacy-dropdown__option.active .privacy-dropdown__option__content,
|
||||
.privacy-dropdown__option.active .privacy-dropdown__option__content strong,
|
||||
.privacy-dropdown__option:hover .privacy-dropdown__option__content,
|
||||
.privacy-dropdown__option:hover .privacy-dropdown__option__content strong,
|
||||
.dropdown-menu__item a:active,
|
||||
.dropdown-menu__item a:focus,
|
||||
.dropdown-menu__item a:hover,
|
||||
.actions-modal ul li:not(:empty) a.active,
|
||||
.actions-modal ul li:not(:empty) a.active button,
|
||||
.actions-modal ul li:not(:empty) a:active,
|
||||
.actions-modal ul li:not(:empty) a:active button,
|
||||
.actions-modal ul li:not(:empty) a:focus,
|
||||
.actions-modal ul li:not(:empty) a:focus button,
|
||||
.actions-modal ul li:not(:empty) a:hover,
|
||||
.actions-modal ul li:not(:empty) a:hover button,
|
||||
.admin-wrapper .sidebar ul li a.selected,
|
||||
.simple_form .block-button,
|
||||
.simple_form .button,
|
||||
.simple_form button {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.dropdown-menu__separator {
|
||||
border-bottom-color: lighten($ui-base-color, 12%);
|
||||
}
|
||||
|
||||
// Change the background colors of modals
|
||||
.actions-modal,
|
||||
.boost-modal,
|
||||
.confirmation-modal,
|
||||
.mute-modal,
|
||||
.report-modal,
|
||||
.embed-modal,
|
||||
.error-modal,
|
||||
.onboarding-modal {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
.boost-modal__action-bar,
|
||||
.confirmation-modal__action-bar,
|
||||
.mute-modal__action-bar,
|
||||
.onboarding-modal__paginator,
|
||||
.error-modal__footer {
|
||||
background: darken($ui-base-color, 6%);
|
||||
|
||||
.onboarding-modal__nav,
|
||||
.error-modal__nav {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: darken($ui-base-color, 12%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.display-case__case {
|
||||
background: $white;
|
||||
}
|
||||
|
||||
.embed-modal .embed-modal__container .embed-modal__html {
|
||||
background: $white;
|
||||
|
||||
&:focus {
|
||||
background: darken($ui-base-color, 6%);
|
||||
}
|
||||
}
|
||||
|
||||
.react-toggle-track {
|
||||
background: $ui-secondary-color;
|
||||
}
|
||||
|
||||
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
||||
background: darken($ui-secondary-color, 10%);
|
||||
}
|
||||
|
||||
.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track {
|
||||
background: lighten($gab-brand-default, 10%);
|
||||
}
|
||||
|
||||
// Change the default color used for the text in an empty column or on the error column
|
||||
.error-column {
|
||||
color: $primary-text-color;
|
||||
background: $white;
|
||||
}
|
||||
|
||||
// Change the default colors used on some parts of the profile pages
|
||||
.activity-stream-tabs {
|
||||
background: $account-background-color;
|
||||
border-bottom-color: lighten($ui-base-color, 8%);
|
||||
}
|
||||
|
||||
.activity-stream {
|
||||
.entry {
|
||||
background: $account-background-color;
|
||||
|
||||
.detailed-status.light,
|
||||
.more.light,
|
||||
.status.light {
|
||||
border-bottom-color: lighten($ui-base-color, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.status.light {
|
||||
.status__content {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
|
||||
.display-name {
|
||||
strong {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accounts-grid {
|
||||
.account-grid-card {
|
||||
|
||||
.name {
|
||||
a {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.username {
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
.account__header__content {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.simple_form,
|
||||
.table-form {
|
||||
.warning {
|
||||
box-shadow: none;
|
||||
background: rgba($error-red, 0.5);
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button.logo-button {
|
||||
color: $white;
|
||||
|
||||
svg {
|
||||
fill: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.public-layout {
|
||||
.header,
|
||||
.public-account-header,
|
||||
.public-account-bio {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: lighten($ui-base-color, 12%);
|
||||
}
|
||||
|
||||
.public-account-header {
|
||||
&__image {
|
||||
background: lighten($ui-base-color, 12%);
|
||||
|
||||
&::after {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
&__name {
|
||||
h1,
|
||||
h1 small {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account-section-headline a.active::after {
|
||||
border-color: transparent transparent $white;
|
||||
}
|
||||
|
||||
.box-widget,
|
||||
.activity-stream,
|
||||
.nothing-here,
|
||||
.directory__tag > a,
|
||||
.directory__tag > div {
|
||||
box-shadow: none;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Dependent colors
|
||||
$black: #000000;
|
||||
$white: #ffffff;
|
||||
|
||||
$classic-base-color: #282c37;
|
||||
$classic-primary-color: #9baec8;
|
||||
$classic-secondary-color: #d9e1e8;
|
||||
$classic-highlight-color: #2b90d9;
|
||||
|
||||
// Differences
|
||||
$success-green: #3c754d;
|
||||
|
||||
$base-overlay-background: $white !default;
|
||||
$valid-value-color: $success-green !default;
|
||||
|
||||
$ui-base-color: $classic-secondary-color !default;
|
||||
$ui-base-lighter-color: #b0c0cf;
|
||||
$ui-primary-color: #9bcbed;
|
||||
$ui-secondary-color: $classic-base-color !default;
|
||||
$ui-highlight-color: #2b5fd9;
|
||||
|
||||
$primary-text-color: $black !default;
|
||||
$darker-text-color: $classic-base-color !default;
|
||||
$dark-text-color: #444b5d;
|
||||
$action-button-color: #606984;
|
||||
|
||||
$inverted-text-color: $black !default;
|
||||
$lighter-text-color: $classic-base-color !default;
|
||||
$light-text-color: #444b5d;
|
||||
|
||||
//Newly added colors
|
||||
$account-background-color: $white !default;
|
||||
|
||||
//Invert darkened and lightened colors
|
||||
@function darken($color, $amount) {
|
||||
@return hsl(hue($color), saturation($color), lightness($color) + $amount);
|
||||
}
|
||||
|
||||
@function lighten($color, $amount) {
|
||||
@return hsl(hue($color), saturation($color), lightness($color) - $amount);
|
||||
}
|
@ -1,194 +0,0 @@
|
||||
.account__header {
|
||||
|
||||
&.inactive {
|
||||
opacity: 0.5;
|
||||
|
||||
.account__header__image,
|
||||
.account__avatar {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
&__image {
|
||||
overflow: hidden;
|
||||
height: 350px;
|
||||
position: relative;
|
||||
background: darken($ui-base-color, 4%);
|
||||
|
||||
&--none {
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
@media screen and (max-width:895px) {
|
||||
height: 225px;
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
margin: 0;
|
||||
|
||||
@include size(100%);
|
||||
}
|
||||
}
|
||||
|
||||
&__bar {
|
||||
display: block;
|
||||
min-height: 74px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: lighten($ui-base-color, 4%);
|
||||
|
||||
@media (min-width:895px) {
|
||||
height: 74px;
|
||||
}
|
||||
}
|
||||
|
||||
&__avatar {
|
||||
display: block;
|
||||
position: absolute;
|
||||
border: 5px solid lighten($ui-base-color, 4%);
|
||||
left: 0;
|
||||
top: -90px;
|
||||
background-color: darken($ui-base-color, 8%);
|
||||
|
||||
@include circle(200px);
|
||||
|
||||
// NOTE - patch fix for avatar size. Wrapper may not be needed when I do polish up on the page
|
||||
.account__avatar {
|
||||
background-size: 200px 200px;
|
||||
|
||||
@include size(200px);
|
||||
}
|
||||
|
||||
@media screen and (max-width:895px) {
|
||||
top: -45px;
|
||||
left: 10px;
|
||||
|
||||
@include size(90px);
|
||||
|
||||
.account__avatar {
|
||||
background-size: 90px 90px;
|
||||
|
||||
@include size(90px);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__extra {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-left: 310px;
|
||||
max-width: 1200px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
@include size(100%);
|
||||
@include margin-center;
|
||||
|
||||
@media (min-width:895px) and (max-width:1190px) {
|
||||
max-width: 900px;
|
||||
padding-left: 300px;
|
||||
}
|
||||
|
||||
@media screen and (max-width:895px) {
|
||||
max-width: 900px;
|
||||
padding: 10px 10px 0 10px;
|
||||
flex-direction: column-reverse;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
&__buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
|
||||
.icon-button {
|
||||
box-sizing: content-box;
|
||||
padding: 2px;
|
||||
|
||||
@include border-design(lighten($ui-base-color, 12%), 1px, 4px);
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&__links {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
color: $darker-text-color;
|
||||
|
||||
@media screen and (max-width:895px) {
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
padding: 16px 22px;
|
||||
text-align: center;
|
||||
|
||||
@media screen and (max-width:1190px) {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
>span {
|
||||
display: block;
|
||||
|
||||
&:first-of-type {
|
||||
color: $primary-text-color;
|
||||
|
||||
@include text-sizing(20px, 800, 24px);
|
||||
|
||||
@media screen and (max-width:895px) {
|
||||
@include text-sizing(16px, 800, 20px);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
color: $ui-secondary-color;
|
||||
padding-top: 2px;
|
||||
|
||||
@include text-sizing(12px, 400, 14px);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
border-bottom: 2px solid $primary-text-color;
|
||||
}
|
||||
|
||||
&.score {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end .account__header__extra
|
||||
@media screen and (max-width:895px) {
|
||||
.account-mobile-container {
|
||||
display: block;
|
||||
background: lighten($ui-base-color, 4%);
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
padding: 10px 10px 0px;
|
||||
|
||||
&--nonuser {
|
||||
padding: 10px 10px 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end .account__header
|
@ -1,10 +0,0 @@
|
||||
.group-account-wrapper {
|
||||
position: relative;
|
||||
|
||||
& > div > .icon-button {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
.group-column-header {
|
||||
overflow: hidden;
|
||||
@include gab-container-standards();
|
||||
.group-column-header__title {
|
||||
padding: 15px;
|
||||
|
||||
@include text-sizing(20px, 700);
|
||||
}
|
||||
.group-column-header__cta {
|
||||
float: right;
|
||||
padding: 15px;
|
||||
font-size: 17px;
|
||||
a {color: #fff;}
|
||||
}
|
||||
}
|
||||
|
||||
.group-card-list {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
|
||||
@include flex(space-between, stretch, row, wrap);
|
||||
}
|
||||
|
||||
.group-card {
|
||||
display: block;
|
||||
flex: 0 0 calc(50% - 20px/2);
|
||||
@include gab-container-standards();
|
||||
margin-bottom: 20px;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
|
||||
.group-card__header {
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
background: $gab-background-container;
|
||||
body.theme-gabsocial-light & {
|
||||
background: $gab-background-container-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-card__content {
|
||||
padding: 15px;
|
||||
|
||||
.group-card__title {
|
||||
color: $primary-text-color;
|
||||
|
||||
@include text-sizing(16px, bold);
|
||||
}
|
||||
|
||||
.group-card__meta {
|
||||
color: $gab-secondary-text;
|
||||
font-size: 14px;
|
||||
|
||||
@include vertical-margin(5px, 10px);
|
||||
}
|
||||
|
||||
.group-card__description {
|
||||
color: $primary-text-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.group-card__title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
.group {
|
||||
.group__header-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.group__header {
|
||||
width: 100%;
|
||||
max-width: 1150px;
|
||||
background: $gab-background-container;
|
||||
body.theme-gabsocial-light & {
|
||||
background: $gab-background-container-light;
|
||||
}
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin: 20px 0;
|
||||
|
||||
.group__cover {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.group__tabs {
|
||||
.group__tabs__tab {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
padding: 16px 22px;
|
||||
text-align: center;
|
||||
color: $primary-text-color;
|
||||
|
||||
&:hover,
|
||||
&--active {
|
||||
border-bottom: 2px solid $primary-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
clear: both;
|
||||
display: table;
|
||||
}
|
||||
|
||||
button {
|
||||
float: right;
|
||||
margin: 7px;
|
||||
}
|
||||
|
||||
div {
|
||||
float: right;
|
||||
margin: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group__panel {
|
||||
padding: 10px 10px 20px 10px;
|
||||
|
||||
h1 {
|
||||
margin-bottom: 10px;
|
||||
|
||||
@include text-sizing(22px, 700);
|
||||
}
|
||||
|
||||
.group__panel__description {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.group__panel__label {
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
padding: 4px 8px;
|
||||
background: $gab-background-container;
|
||||
body.theme-gabsocial-light & {
|
||||
background: $gab-background-container-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group__feed {
|
||||
background: $gab-background-container;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
body.theme-gabsocial-light & {
|
||||
background: $gab-background-container-light;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
.group-form {
|
||||
padding: 20px;
|
||||
@include gab-container-standards();
|
||||
&,
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
input[type=text],
|
||||
textarea {
|
||||
&.standard {
|
||||
width: 100%;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
}
|
||||
textarea {
|
||||
float: left;
|
||||
height: 88px;
|
||||
}
|
||||
.group-form__file-label {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
height: 20px;
|
||||
padding: 3px 0 0 33px;
|
||||
color: $gab-secondary-text;
|
||||
|
||||
@include text-sizing(12px, 400);
|
||||
@include background-image('/assets/images/sprite-post-functions.png', 100px 1200px);
|
||||
|
||||
&:hover {
|
||||
color: $gab-brand-default;
|
||||
background-position: 0 -100px;
|
||||
}
|
||||
&.group-form__file-label--selected {
|
||||
background-position: 0 -100px;
|
||||
color: $gab-brand-default;;
|
||||
}
|
||||
}
|
||||
.group-form__file {
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
|
||||
@include size(1px);
|
||||
}
|
||||
button {float: right;}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
.group-sidebar-panel {
|
||||
&__items {
|
||||
padding: 0 15px 15px;
|
||||
|
||||
&__show-all {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: block;
|
||||
color: $primary-text-color;
|
||||
text-decoration: none;
|
||||
margin-bottom: 15px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__meta {
|
||||
font-size: 0.8em;
|
||||
color: $gab-secondary-text;
|
||||
|
||||
&__unread {
|
||||
color: $gab-brand-default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
input[type='text'],
|
||||
textarea {
|
||||
&.standard {
|
||||
box-sizing: border-box;
|
||||
padding: 7px 10px;
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
color: $gab-brand-default;
|
||||
border-color: $gab-placeholder-accent;
|
||||
background: $gab-background-container;
|
||||
|
||||
@include text-sizing(16px, 400, 18);
|
||||
@include input-placeholder {
|
||||
color: $gab-placeholder-accent;
|
||||
}
|
||||
|
||||
body.theme-gabsocial-light & {
|
||||
color: $gab-placeholder-accent;
|
||||
border-color: $gab-secondary-text;
|
||||
background: $gab-background-base-light;
|
||||
|
||||
@include input-placeholder {
|
||||
color: $gab-secondary-text;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textarea.standard {
|
||||
resize: vertical;
|
||||
}
|
@ -1,451 +0,0 @@
|
||||
.onboarding-modal,
|
||||
.error-modal,
|
||||
.embed-modal {
|
||||
background: $ui-secondary-color;
|
||||
color: $inverted-text-color;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.error-modal__body {
|
||||
position: relative;
|
||||
|
||||
@include size(80vw, 80vh);
|
||||
@include max-size(520px, 420px);
|
||||
|
||||
&>div {
|
||||
box-sizing: border-box;
|
||||
padding: 25px;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
user-select: text;
|
||||
|
||||
@include size(100%);
|
||||
@include abs-position(0, auto, auto, 0);
|
||||
@include flex(center, center, column);
|
||||
}
|
||||
}
|
||||
|
||||
.error-modal__body {
|
||||
text-align: center;
|
||||
|
||||
@include flex(center, center, column);
|
||||
}
|
||||
|
||||
.onboarding-modal__paginator,
|
||||
.error-modal__footer {
|
||||
flex: 0 0 auto;
|
||||
background: darken($ui-secondary-color, 8%);
|
||||
display: flex;
|
||||
padding: 25px;
|
||||
|
||||
&>div {
|
||||
min-width: 33px;
|
||||
}
|
||||
|
||||
.onboarding-modal__nav,
|
||||
.error-modal__nav {
|
||||
color: $lighter-text-color;
|
||||
border: 0;
|
||||
padding: 10px 25px;
|
||||
height: auto;
|
||||
margin: -10px;
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
|
||||
@include text-sizing(14px, 500, inherit);
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: darken($lighter-text-color, 4%);
|
||||
background-color: darken($ui-secondary-color, 16%);
|
||||
}
|
||||
|
||||
&.onboarding-modal__done,
|
||||
&.onboarding-modal__next {
|
||||
color: $inverted-text-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: lighten($inverted-text-color, 4%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error-modal__footer {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.display-case {
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
&__label {
|
||||
color: $inverted-text-color;
|
||||
margin-bottom: 5px;
|
||||
text-transform: uppercase;
|
||||
|
||||
@include text-sizing(12px, 500);
|
||||
}
|
||||
|
||||
&__case {
|
||||
background: $ui-base-color;
|
||||
color: $secondary-text-color;
|
||||
font-weight: 500;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.onboard-sliders {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
|
||||
@include max-size(30px, auto);
|
||||
}
|
||||
|
||||
.boost-modal,
|
||||
.confirmation-modal,
|
||||
.report-modal,
|
||||
.actions-modal,
|
||||
.mute-modal {
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
width: 480px;
|
||||
max-width: 90vw;
|
||||
color: $gab-secondary-text;
|
||||
|
||||
@include border-design($gab-placeholder-accent, 1px, 4px);
|
||||
|
||||
body.theme-gabsocial-light & {
|
||||
color: $gab-default-text-light;
|
||||
}
|
||||
|
||||
background: $gab-background-container;
|
||||
|
||||
.status__display-name {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.status__avatar {
|
||||
height: 28px;
|
||||
left: 10px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
width: 48px;
|
||||
}
|
||||
|
||||
.status__content__spoiler-link {
|
||||
color: lighten($secondary-text-color, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.actions-modal {
|
||||
.status {
|
||||
background: $white;
|
||||
border-bottom-color: $ui-secondary-color;
|
||||
|
||||
@include vertical-padding(10px);
|
||||
}
|
||||
|
||||
.dropdown-menu__separator {
|
||||
display: block;
|
||||
margin: 10px;
|
||||
height: 1px;
|
||||
background: $gab-background-base;
|
||||
}
|
||||
}
|
||||
|
||||
.boost-modal__container {
|
||||
overflow-x: scroll;
|
||||
padding: 10px;
|
||||
|
||||
.status {
|
||||
user-select: text;
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.boost-modal__action-bar,
|
||||
.confirmation-modal__action-bar,
|
||||
.mute-modal__action-bar {
|
||||
background: $ui-secondary-color;
|
||||
padding: 10px;
|
||||
line-height: 36px;
|
||||
|
||||
@include flex(space-between);
|
||||
|
||||
&>div {
|
||||
flex: 1 1 auto;
|
||||
text-align: right;
|
||||
color: $lighter-text-color;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.boost-modal__status-header {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.boost-modal__status-time {
|
||||
float: right;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.mute-modal {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.mute-modal .react-toggle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.report-modal {
|
||||
width: 90vw;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.report-modal__container {
|
||||
display: flex;
|
||||
border-top: 1px solid $ui-secondary-color;
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
flex-wrap: wrap;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.report-modal__statuses,
|
||||
.report-modal__comment {
|
||||
box-sizing: border-box;
|
||||
width: 50%;
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.report-modal__statuses {
|
||||
flex: 1 1 auto;
|
||||
min-height: 20vh;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
.status__content a {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
|
||||
.status__content,
|
||||
.status__content p {
|
||||
color: $gab-secondary-text;
|
||||
|
||||
body.theme-gabsocial-light & {
|
||||
color: $gab-default-text-light;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
max-height: 10vh;
|
||||
}
|
||||
}
|
||||
|
||||
.report-modal__comment {
|
||||
padding: 20px;
|
||||
border-right: 1px solid $ui-secondary-color;
|
||||
max-width: 320px;
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.setting-text {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
color: $inverted-text-color;
|
||||
background: $white;
|
||||
padding: 10px;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
margin-bottom: 20px;
|
||||
|
||||
@include border-design($ui-secondary-color, 1px, 4px);
|
||||
|
||||
&:focus {
|
||||
border: 1px solid darken($ui-secondary-color, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
.setting-toggle {
|
||||
@include vertical-margin(20px, 24px);
|
||||
|
||||
&__label {
|
||||
color: $inverted-text-color;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
padding: 10px;
|
||||
max-width: 100%;
|
||||
order: 2;
|
||||
|
||||
.setting-toggle {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions-modal {
|
||||
.status {
|
||||
overflow-y: auto;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
width: calc(100% - 72px);
|
||||
margin: 35px;
|
||||
|
||||
.actions-modal__item-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
ul {
|
||||
overflow-y: auto;
|
||||
flex-shrink: 0;
|
||||
max-height: calc(100vh - 147px);
|
||||
|
||||
// NOTE - not sure what this is yet, leaving alone for now until I find out.
|
||||
&.with-status {
|
||||
max-height: calc(80vh - 75px);
|
||||
}
|
||||
|
||||
li:empty {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li:not(:empty) {
|
||||
&:first-of-type {
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 13px 10px 12px;
|
||||
font-size: 14px;
|
||||
color: $gab-secondary-text;
|
||||
text-decoration: none;
|
||||
|
||||
&,
|
||||
button {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
|
||||
&,
|
||||
button {
|
||||
background: $gab-background-base;
|
||||
color: $gab-text-highlight;
|
||||
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
button:first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.confirmation-modal__action-bar,
|
||||
.mute-modal__action-bar {
|
||||
|
||||
.confirmation-modal__secondary-button,
|
||||
.confirmation-modal__cancel-button,
|
||||
.mute-modal__cancel-button {
|
||||
background-color: transparent;
|
||||
color: $lighter-text-color;
|
||||
|
||||
@include text-sizing(14px, 500);
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: darken($lighter-text-color, 4%);
|
||||
}
|
||||
}
|
||||
|
||||
.confirmation-modal__secondary-button {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.confirmation-modal__container,
|
||||
.mute-modal__container,
|
||||
.report-modal__target {
|
||||
padding: 30px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
|
||||
strong {
|
||||
font-weight: 500;
|
||||
|
||||
@each $lang in $cjk-langs {
|
||||
&:lang(#{$lang}) {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.report-modal__target {
|
||||
padding: 20px;
|
||||
|
||||
.media-modal__close {
|
||||
top: 19px;
|
||||
right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-layout {
|
||||
background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}"/></svg>') repeat-x bottom fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@include breakpoint(sm) {
|
||||
.account-header {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
.status-revisions-root {
|
||||
@media screen and (max-width: 960px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.status-revisions {
|
||||
padding: 8px 0 0;
|
||||
overflow: hidden;
|
||||
background-color: $classic-base-color;
|
||||
border-radius: 6px;
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
height: 90vh;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: block;
|
||||
position: relative;
|
||||
border-bottom: 1px solid lighten($classic-base-color, 8%);
|
||||
border-radius: 6px 6px 0 0;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
|
||||
&__title {
|
||||
display: block;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
color: $primary-text-color;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
&__close {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 500px;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
height: calc(100% - 80px);
|
||||
-webkit-overflow-scrolling: touch;
|
||||
widows: 90%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-list {
|
||||
width: 100%;
|
||||
|
||||
&__error {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__item {
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid lighten($classic-base-color, 8%);
|
||||
|
||||
&__timestamp {
|
||||
opacity: 0.5;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -36,17 +36,3 @@
|
||||
url('../fonts/roboto/roboto-bold-700.ttf') format('truetype'),
|
||||
url('../fonts/roboto/roboto-bold-700.svg') format('svg');
|
||||
}
|
||||
|
||||
// Montserrat Extra Bold
|
||||
// Used for all bold number, scoreboard, count displays
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
src: url('../fonts/montserrat/montserrat-extra-bold-800.eot?#iefix');
|
||||
src: url('../fonts/montserrat/montserrat-extra-bold-800.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/montserrat/montserrat-extra-bold-800.woff2') format('woff2'),
|
||||
url('../fonts/montserrat/montserrat-extra-bold-800.woff') format('woff'),
|
||||
url('../fonts/montserrat/montserrat-extra-bold-800.ttf') format('truetype'),
|
||||
url('../fonts/montserrat/montserrat-extra-bold-800.svg') format('svg');
|
||||
}
|
@ -273,7 +273,7 @@ body {
|
||||
background-color: #d9e0e5;
|
||||
}
|
||||
|
||||
.backgroundcolorSecondary3 {
|
||||
.backgroundColorSecondary3 {
|
||||
background-color: #F6F6F9;
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ ca:
|
||||
themes:
|
||||
contrast: Gab Social (Alt contrast)
|
||||
default: Gab Social (Fosc)
|
||||
gabsocial-light: Gab Social (Clar)
|
||||
gabsocial-light: Clar
|
||||
time:
|
||||
formats:
|
||||
default: "%b %d, %Y, %H:%M"
|
||||
|
@ -1005,7 +1005,7 @@ co:
|
||||
themes:
|
||||
contrast: Gab Social (Cuntrastu altu)
|
||||
default: Gab Social (Scuru)
|
||||
gabsocial-light: Gab Social (Chjaru)
|
||||
gabsocial-light: Chjaru
|
||||
time:
|
||||
formats:
|
||||
default: "%d %b %Y, %H:%M"
|
||||
|
@ -1021,7 +1021,7 @@ cs:
|
||||
themes:
|
||||
contrast: Gab Social (vysoký kontrast)
|
||||
default: Gab Social (tmavý)
|
||||
gabsocial-light: Gab Social (světlý)
|
||||
gabsocial-light: světlý
|
||||
time:
|
||||
formats:
|
||||
default: "%d. %b %Y, %H:%M"
|
||||
|
@ -947,7 +947,7 @@ cy:
|
||||
themes:
|
||||
contrast: Cyferbyniad uchel
|
||||
default: Gab Social
|
||||
gabsocial-light: Gab Social (golau)
|
||||
gabsocial-light: golau
|
||||
time:
|
||||
formats:
|
||||
default: "%b %d, %Y, %H:%M"
|
||||
|
@ -743,7 +743,7 @@ da:
|
||||
themes:
|
||||
contrast: Gab Social (Høj kontrast)
|
||||
default: Gab Socialt (Mørk)
|
||||
gabsocial-light: Gab Social (Lys)
|
||||
gabsocial-light: Lys
|
||||
time:
|
||||
formats:
|
||||
default: "%b %d, %Y, %H:%M"
|
||||
|