diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index baa3c2c61f57..bf456f1547ee 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve the Open Food Facts mobile app (iPhone and Android) title: "" -labels: "bug" +type: "🐛 Bug" assignees: "" --- diff --git a/.github/ISSUE_TEMPLATE/epic.md b/.github/ISSUE_TEMPLATE/epic.md index afe071efd9d6..45879db591d9 100644 --- a/.github/ISSUE_TEMPLATE/epic.md +++ b/.github/ISSUE_TEMPLATE/epic.md @@ -3,7 +3,7 @@ name: Epic about: Template for epics. Epics group several user stories together into a main piece of added value. title: '' -labels: "epic" +type: "🎯 Epic" assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index d7bc0190c310..31446cc5af4c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: 'enhancement' +type: '✨ Enhancement' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md index 5d8060401c2a..b012a2319524 100644 --- a/.github/ISSUE_TEMPLATE/task.md +++ b/.github/ISSUE_TEMPLATE/task.md @@ -3,7 +3,7 @@ name: Task about: Template for tasks. Tasks are a small unit of work, usually resulting of breaking down a user story or other bigger items of a sprint backlog. title: '' -labels: '✔ task' +type: '✅ Task' assignees: '' --- diff --git a/packages/scanner/shared/pubspec.yaml b/packages/scanner/shared/pubspec.yaml index 942e7faec42b..5ba8164d0c91 100644 --- a/packages/scanner/shared/pubspec.yaml +++ b/packages/scanner/shared/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_svg: 2.0.13 + flutter_svg: 2.0.14 visibility_detector: 0.4.0+2 provider: 6.1.2 diff --git a/packages/smooth_app/assets/fonts/SmoothIcons.ttf b/packages/smooth_app/assets/fonts/SmoothIcons.ttf index 8874992513cf..c101e0460053 100644 Binary files a/packages/smooth_app/assets/fonts/SmoothIcons.ttf and b/packages/smooth_app/assets/fonts/SmoothIcons.ttf differ diff --git a/packages/smooth_app/assets/fonts/icons/app_store.svg b/packages/smooth_app/assets/fonts/icons/app_store.svg new file mode 100644 index 000000000000..f2b4288502c7 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/app_store.svg @@ -0,0 +1,7 @@ + + + app_store + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/camera_happy.svg b/packages/smooth_app/assets/fonts/icons/camera_happy.svg new file mode 100644 index 000000000000..c6ccf0d615aa --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/camera_happy.svg @@ -0,0 +1,7 @@ + + + Camera happy + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/config.json b/packages/smooth_app/assets/fonts/icons/config.json index 399ebc2a13bf..f5e20197a1bc 100644 --- a/packages/smooth_app/assets/fonts/icons/config.json +++ b/packages/smooth_app/assets/fonts/icons/config.json @@ -1005,6 +1005,398 @@ "search": [ "add_to_list" ] + }, + { + "uid": "c15b5b49cdbc8bc7f84fb6aed59250cb", + "css": "eye_visible", + "code": 59464, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500.1 133.3C188.4 133.3 40.4 402.8 4.5 479.7-1.5 492.5-1.5 507.4 4.5 520.2 40.4 597.2 188.4 866.7 500.1 866.7 810.7 866.7 958.8 599.1 995.3 521.1 1001.6 507.7 1001.6 492.3 995.3 478.9 958.8 400.9 810.7 133.3 500.1 133.3ZM500 266.7C628.8 266.7 733.3 371.2 733.3 500 733.3 628.8 628.8 733.3 500 733.3 371.2 733.3 266.7 628.8 266.7 500 266.7 371.2 371.2 266.7 500 266.7ZM500 366.7C426.4 366.7 366.7 426.4 366.7 500 366.7 573.6 426.4 633.3 500 633.3 573.6 633.3 633.3 573.6 633.3 500 633.3 426.4 573.6 366.7 500 366.7Z", + "width": 1000 + }, + "search": [ + "eye_visible" + ] + }, + { + "uid": "d3a7590350164ffe8f23de0e9c2885d9", + "css": "eye_invisible", + "code": 59393, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M56.9 19.7L9.8 66.8 943.1 1000.1 990.2 953 789.4 752.2C925.9 659.7 993.3 530.5 994.2 528.7 998 523.2 1000 516.6 1000 509.9 1000 502.4 997.4 495.1 992.8 489.2 989.3 483.6 797.3 176.6 500 176.6 415.7 176.6 340 201.6 274.5 237.2L56.9 19.7ZM500 276.6C628.9 276.6 733.3 381 733.3 509.9 733.3 562.3 715.7 610.3 686.5 649.2L590 552.8C596.3 539.8 600 525.3 600 509.9 600 454.7 555.2 409.9 500 409.9 484.6 409.9 470.1 413.6 457.1 419.9L360.7 323.4C399.6 294.2 447.6 276.6 500 276.6ZM165 312.4C66 395.8 9.2 486.1 7.3 489.1 2.6 495 0 502.4 0 509.9 0 516.4 1.9 522.7 5.4 528.1 5.4 528.1 5.5 528.2 5.5 528.3 6.1 529.4 167.3 843.2 500 843.2 561.7 843.2 617.4 832.4 667.3 814.8L581.1 728.5C555.8 737.9 528.5 743.2 500 743.2 371.1 743.2 266.7 638.8 266.7 509.9 266.7 481.4 272 454.1 281.4 428.8L165 312.4Z", + "width": 1000 + }, + "search": [ + "eye_invisible" + ] + }, + { + "uid": "b9562e729d528a8431c2b7e44de64d91", + "css": "delete_trash", + "code": 59466, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M452.8 0C374.3 0 309.9 64.4 309.9 142.9L59.9 142.9C47 142.7 35 149.4 28.6 160.6 22.1 171.7 22.1 185.5 28.6 196.6 35 207.7 47 214.5 59.9 214.3L119.4 214.3 119.4 821.4C119.4 893.6 178.2 952.4 250.4 952.4L491.6 952.4C438.2 896.8 405.1 821.3 405.1 738.1 405.1 639.1 451.8 551.1 524.2 494.5L524.2 369C524.2 349.3 540.2 333.3 559.9 333.3 579.6 333.3 595.6 349.3 595.6 369L595.6 452.4C632.3 437.1 672.5 428.6 714.7 428.6 739.3 428.6 763.1 431.7 786.1 437.2L786.1 214.3 845.6 214.3C858.5 214.5 870.5 207.7 877 196.6 883.5 185.5 883.5 171.7 877 160.6 870.5 149.4 858.5 142.7 845.6 142.9L595.6 142.9C595.6 64.4 531.2 0 452.8 0ZM452.8 71.4C492.6 71.4 524.2 103 524.2 142.9L381.3 142.9C381.3 103 412.9 71.4 452.8 71.4ZM345.6 333.3C365.3 333.3 381.3 349.3 381.3 369L381.3 726.2C381.3 745.9 365.3 761.9 345.6 761.9 325.9 761.9 309.9 745.9 309.9 726.2L309.9 369C309.9 349.3 325.9 333.3 345.6 333.3ZM714.7 476.2C570 476.2 452.8 593.5 452.8 738.1 452.8 882.7 570 1000 714.7 1000 859.3 1000 976.6 882.7 976.6 738.1 976.6 593.5 859.3 476.2 714.7 476.2ZM595.6 595.2C601.7 595.2 607.8 597.6 612.5 602.2L714.7 704.4 816.9 602.2C826.2 592.9 841.2 592.9 850.6 602.2 859.9 611.5 859.9 626.6 850.6 635.9L748.3 738.1 850.6 840.3C859.9 849.6 859.9 864.7 850.6 874 845.9 878.6 839.8 881 833.7 881 827.6 881 821.5 878.6 816.9 874L714.7 771.8 612.5 874C607.8 878.6 601.7 881 595.6 881 589.5 881 583.4 878.6 578.8 874 569.5 864.7 569.5 849.6 578.8 840.3L681 738.1 578.8 635.9C569.5 626.6 569.5 611.5 578.8 602.2 583.4 597.6 589.5 595.2 595.6 595.2Z", + "width": 1000 + }, + "search": [ + "delete_trash" + ] + }, + { + "uid": "2d19b1cc3c0954309eec2acd7127bff8", + "css": "image_check", + "code": 59467, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M303.6 581.4L482.3 760.3C488.2 787.7 498.2 813.6 511.7 837.3L101.2 837.3C86.2 837.2 71.3 833.8 57.8 827.2L303.6 581.4ZM708.3 95.2C764.2 95.2 809.5 140.5 809.5 196.4L809.6 435.1C790.4 430.8 770.5 428.6 750 428.6 667.3 428.6 593.2 465.2 543 523.1L529.8 509.9C516.6 496.7 495.3 496.7 482.1 509.9L404.8 587.2 327.4 509.9C314.2 496.9 293 496.9 279.7 509.9L10.1 779.5C3.5 766 0.1 751.1 0 736.1L0 196.4C0 140.5 45.3 95.2 101.2 95.2L708.3 95.2ZM479.2 661.7L452.5 634.9 502.7 584.7C491.3 608.7 483.2 634.5 479.2 661.7ZM573.4 230.2C517.5 230.2 472.2 275.5 472.2 331.3 472.2 387.2 517.5 432.5 573.4 432.5 629.3 432.5 674.6 387.2 674.6 331.3 674.6 275.5 629.3 230.2 573.4 230.2ZM573.4 297.6C592 297.6 607.1 312.7 607.1 331.3 607.1 350 592 365.1 573.4 365.1 554.8 365.1 539.7 350 539.7 331.3 539.7 312.7 554.8 297.6 573.4 297.6ZM752.4 476.2C626.7 476.2 523.8 579 523.8 704.8 523.8 830.5 626.7 933.3 752.4 933.3 878.1 933.3 980.9 830.5 980.9 704.8 980.9 662.8 969.5 624.8 950.5 590.5L735.2 805.7C731.4 809.5 727.6 811.4 721.9 811.4 716.2 811.4 712.4 809.5 708.5 805.7L622.8 720C615.2 712.4 615.2 700.9 622.8 693.3 630.5 685.7 641.9 685.7 649.5 693.3L721.9 765.7 927.6 558.1C885.7 508.6 822.8 476.2 752.4 476.2ZM927.6 558.1C937.1 567.6 944.7 579 950.5 590.5L994.2 546.6C1001.9 539 1001.9 527.6 994.2 518.1 986.6 510.5 975.2 510.5 967.6 518.1L927.6 558.1Z", + "width": 1000 + }, + "search": [ + "image_check" + ] + }, + { + "uid": "b6303cfee0413dd05e8255b59a58aa3c", + "css": "image_add", + "code": 59468, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M764.4 428.3C894.5 428.3 1000 533.8 1000 663.9 1000 794 894.5 899.5 764.4 899.5 634.3 899.5 528.8 794 528.8 663.9 528.8 533.8 634.3 428.3 764.4 428.3ZM303.6 581.4L497.9 775.8C507 797.8 518.8 818.5 532.9 837.3L101.2 837.3C86.2 837.2 71.3 833.8 57.8 827.2L303.6 581.4ZM764.4 491.1C752.6 491.1 743 500.6 743 512.5L743 642.5 613 642.5C601.1 642.5 591.6 652.1 591.6 663.9 591.6 669.8 593.9 675.2 597.8 679.1 601.7 683 607.1 685.3 613 685.3L743 685.3 743 815.4C743 821.3 745.4 826.6 749.3 830.5 753.1 834.4 758.5 836.8 764.4 836.8 776.3 836.8 785.8 827.2 785.8 815.4L785.8 685.3 915.9 685.3C927.7 685.3 937.3 675.8 937.3 663.9 937.3 652.1 927.7 642.5 915.9 642.5L785.8 642.5 785.8 512.5C785.8 506.6 783.4 501.2 779.6 497.3 775.7 493.5 770.3 491.1 764.4 491.1ZM708.3 95.2C764.2 95.2 809.5 140.5 809.5 196.4L809.6 384.7C794.1 382.1 778.1 380.7 761.9 380.7 717.8 380.7 676 390.7 638.7 408.6 660.7 390.1 674.6 362.3 674.6 331.3 674.6 275.5 629.3 230.2 573.4 230.2 517.5 230.2 472.2 275.5 472.2 331.3 472.2 387.2 517.5 432.5 573.4 432.5 584.7 432.5 595.5 430.7 605.6 427.3 573.9 448 546.6 474.8 525.4 506.1 512.2 496.9 493.9 498.1 482.1 509.9L404.8 587.2 327.4 509.9C314.2 496.9 293 496.9 279.7 509.9L10.1 779.5C3.5 766 0.1 751.1 0 736.1L0 196.4C0 140.5 45.3 95.2 101.2 95.2L708.3 95.2ZM476.3 658.8L452.5 634.9 482.9 604.5C479 622 476.8 640.2 476.3 658.8ZM573.4 297.6C592 297.6 607.1 312.7 607.1 331.3 607.1 350 592 365.1 573.4 365.1 554.8 365.1 539.7 350 539.7 331.3 539.7 312.7 554.8 297.6 573.4 297.6Z", + "width": 1000 + }, + "search": [ + "image_add" + ] + }, + { + "uid": "a56b0a2aa9249d396d1cdffed9d14944", + "css": "language", + "code": 59430, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M83.3 0C37.3 0 0 37.3 0 83.3L0 708.3C0 754.4 37.3 791.7 83.3 791.7L250 791.7 250 958.3C250 981.3 268.7 1000 291.7 1000 305.8 1000 318.9 992.8 326.6 981L468.8 791.7 916.7 791.7C962.7 791.7 1000 754.4 1000 708.3L1000 83.3C1000 37.3 962.7 0 916.7 0L83.3 0ZM250 125C266.7 125 281.8 134.9 288.3 150.2L413.3 441.9C422.4 463 412.6 487.6 391.4 496.7 386.1 499 380.5 500 375 500 358.8 500 343.4 490.6 336.7 474.8L329.7 458.3 170.3 458.3 163.3 474.8C154.3 495.9 129.6 505.8 108.6 496.7 87.4 487.6 77.6 463.1 86.7 442L211.7 150.3C218.2 134.9 233.3 125 250 125ZM750 250.1C773 250.1 791.7 268.7 791.7 291.7L791.7 333.4 875 333.4C898 333.4 916.7 352 916.7 375.1 916.7 398.1 898 416.7 875 416.7L870.4 416.7C861.7 460 840.7 510.6 809.5 555L858.3 591.6C876.7 605.4 880.5 631.6 866.7 650 858.5 660.9 845.9 666.6 833.3 666.6 824.6 666.6 815.8 663.9 808.3 658.3L753.2 616.9C717 646.9 673.9 666.7 625 666.7 602 666.7 583.3 648 583.3 625 583.3 602 602 583.3 625 583.3 645.9 583.3 665.6 576.3 683.8 564.9L641.7 533.4C623.3 519.6 619.5 493.4 633.3 475 647.1 456.6 673.2 453 691.7 466.7L743.6 505.6C763.1 477.3 777.5 445.3 785.2 416.7L625 416.7C602 416.7 583.3 398.1 583.3 375.1 583.3 352 602 333.4 625 333.4L708.3 333.4 708.3 291.7C708.3 268.7 727 250.1 750 250.1ZM250 272.5L206.1 375 293.9 375 250 272.5Z", + "width": 1000 + }, + "search": [ + "language" + ] + }, + { + "uid": "a6a90870f2e9c2a077088c9bd78773c2", + "css": "camera_happy", + "code": 59434, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M900 150.1L742.1 150.1 650 50 349.9 50.2 258.2 150.1 100 150.1C45 150.1 0 195.1 0 250.1L0 850.1C0 905.1 45 950.1 100 950.1L900 950.1C955 950.1 1000 905.1 1000 850.1L1000 250.1C1000 195.1 955 150.1 900 150.1ZM625 350.1C666.4 350.1 700 383.7 700 425.1 700 466.5 666.4 500.1 625 500.1 583.6 500.1 550 466.5 550 425.1 550 383.7 583.6 350.1 625 350.1ZM375 350.1C416.4 350.1 450 383.7 450 425.1 450 466.5 416.4 500.1 375 500.1 333.6 500.1 300 466.5 300 425.1 300 383.7 333.6 350.1 375 350.1ZM500 750.1C341.7 750.1 261.7 632.8 258.4 627.9L341.4 572.1C343.6 575.3 396.4 650.1 500 650.1 603.5 650.1 656.4 575.3 658.6 572L741.6 627.8C738.3 632.8 658.3 750.1 500 750.1Z", + "width": 1000 + }, + "search": [ + "camera_happy" + ] + }, + { + "uid": "fa3b24c96010858c33aa77974da67027", + "css": "contribute", + "code": 59476, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M545.5 45.5C495.2 45.5 454.5 86.2 454.5 136.4 454.5 186.6 495.2 227.3 545.5 227.3 595.7 227.3 636.4 186.6 636.4 136.4 636.4 86.2 595.7 45.5 545.5 45.5L545.5 45.5ZM321.7 227.7C315.7 228.2 309.7 229.3 303.9 231L172.5 269.4C154.2 274.7 138.5 286.4 128.4 302.1L75.5 385.4 57.7 377.2C51.7 374.3 45 373 38.3 373.3 19.8 374 4.3 387 0.7 404.6-2.8 422.2 6.6 439.8 23.5 447.2L40.8 455.2C43 474.8 60.2 489.7 80.6 489.7 88.3 489.7 95.9 487.5 102.3 483.4L518.8 674.6 520.3 683C520.3 683.1 520.3 683.3 520.3 683.4 520.3 704.8 538.2 722.1 560.3 722.1 572.3 722.1 583.7 716.9 591.3 707.9L721.2 767.5C712.4 785.7 704 799.6 695.7 799.6 666.6 799.6 633.5 815.3 613.9 852.1 603.2 872.3 560.3 954.5 560.3 954.5L1000 954.5C1000 954.5 893.7 735.5 880.5 709 856.8 661.3 829.8 644.6 814.2 644.6 789.5 644.6 770.6 668.4 754.8 697.2L593.3 623.1 565.7 381.3C562.3 352.2 544.3 326.5 517.6 312.6L374 237.8C357.8 229.4 339.6 226 321.7 227.7ZM272.7 318.2L215 454.5 136.4 416.7 184.5 343.1 272.7 318.2ZM467.9 409.1L500 545.5 409.1 514.2 467.9 409.1ZM179.2 590.9L92.5 904.6C91.5 908.1 90.9 911.7 90.9 915.4 90.9 937 109.2 954.5 131.8 954.5 147.2 954.5 161.3 946.3 168.3 933.1L168.3 933.1 169.5 930.6C169.6 930.4 169.7 930.2 169.8 930.1L289.5 667.1 384 737.5 418.6 920.8C421.4 940.1 438.7 954.5 459.1 954.5 481.5 954.5 499.8 937.2 500 915.7L500 736.4 179.2 590.9Z", + "width": 1000 + }, + "search": [ + "contribute" + ] + }, + { + "uid": "844c8bbff89119bde988544a73643ebe", + "css": "crash", + "code": 59477, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M462.5 121.8C446.8 122.5 433.4 133.5 429.6 148.8L368.4 393.8 156.9 303.1C144.2 297.7 129.6 300.1 119.2 309.2 108.9 318.3 104.7 332.6 108.5 345.8L172.4 569.5 17.3 662.5C6.9 668.8 0.3 680 0 692.3-0.3 704.5 5.7 716.1 15.9 722.9L230.2 865.7C240.8 873 254.5 874.1 266.1 868.4 277.7 862.8 285.3 851.3 286.1 838.4 286.9 825.5 280.6 813.3 269.8 806.3L102.4 694.7 232.6 616.6C246.5 608.3 253 591.7 248.6 576.2L197.8 398.4 378.7 476C388.4 480.1 399.3 479.8 408.7 475.2 418.1 470.5 425 462 427.5 451.8L477.4 252.4 576.1 425.1C584.8 440.4 603.3 447 619.7 440.8L835.3 360 751.8 610.4C745.8 628.4 754.9 647.8 772.4 654.8L894.1 703.5 763.4 808.1C753.4 816.1 748.4 828.8 750.4 841.4 752.3 854 760.8 864.6 772.7 869.3 784.6 873.9 798 871.9 808 863.9L986.6 721C996.5 713.1 1001.4 700.5 999.6 687.9 997.7 675.4 989.3 664.7 977.5 660L830.2 601.1 926.7 311.6C931.1 298.5 927.5 284.1 917.6 274.6 907.7 265 893.2 262 880.3 266.9L623 363.3 495.3 139.7C488.6 128 476 121.1 462.5 121.8ZM496.7 445.3L464.3 657.4 357.1 550.3 428.3 729 285.7 728.9 428.5 800.3 321.4 871.7 714.3 871.7 607.1 800.3 750 728.9 607.1 728.9 678.5 550.3 535.7 657.4 496.7 445.3Z", + "width": 1000 + }, + "search": [ + "crash" + ] + }, + { + "uid": "d7d3a3e975ea304ff3983e77b44c810c", + "css": "currency", + "code": 59478, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M505 0C471 0 440.7 15 419.6 38.5L312.8 38.5C285.6 38.5 266.9 66 277 91.2L312.7 192.3 697.3 192.3 733 91.2C743.1 66 724.4 38.5 697.2 38.5L590.4 38.5C569.3 15 539.1 0 505 0ZM312.7 269.2C312.7 269.2 43.5 500 43.5 769.2 43.5 923.1 158.9 1000 235.8 1000L505 1000 774.2 1000C851.2 1000 966.6 923.1 966.6 769.2 966.6 500 697.3 269.2 697.3 269.2L312.7 269.2Z", + "width": 1000 + }, + "search": [ + "currency" + ] + }, + { + "uid": "45bb8b419138088663be80e2ab0ccb90", + "css": "nutritional_facts", + "code": 59479, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M344.8 0C395.9 0 437.9 42.1 437.9 93.1L562.1 93.1C613.1 93.1 655.2 135.2 655.2 186.2L655.2 629.4C676.9 615.5 701.4 605.7 727.7 600.9 722.8 615.8 720.5 629.4 720.5 640 720.5 676.1 743.8 685.7 757.5 685.7 816.5 685.7 864 673.6 899.1 649.8 941.1 687.7 965.5 741.1 965.5 799.1 965.5 910.4 875 1000.9 763.8 1000.9 665.8 1000.9 583.9 930.6 565.8 837.8L562.1 837.9 127.6 837.9C76.5 837.9 34.5 795.9 34.5 744.8L34.5 186.2C34.5 135.2 76.5 93.1 127.6 93.1L251.7 93.1C251.7 42.1 293.8 0 344.8 0ZM251.7 155.2L127.6 155.2C110.1 155.2 96.6 168.7 96.6 186.2L96.6 744.8C96.6 762.4 110.1 775.9 127.6 775.9L562.1 775.9C562.5 775.9 563 775.9 563.5 775.8 567 745.2 577.4 716.7 593.1 691.9L593.1 186.2C593.1 168.7 579.6 155.2 562.1 155.2L437.9 155.2 437.9 186.2C437.9 203.3 424 217.2 406.9 217.2L282.8 217.2C265.6 217.2 251.7 203.3 251.7 186.2L251.7 155.2ZM934 496.6C937.1 496.6 939.7 498.8 940.2 501.8 940.6 504.2 949.4 560.3 911 605.7 882.7 639 836.7 657.1 774.5 659.9 773.1 660.2 771.6 660.5 770.1 660.5 769 660.5 768 660.3 767 660.1 763.8 660.2 760.8 660.4 757.5 660.4 754 660.4 745.7 658.4 745.7 640 745.7 633.3 747 625.3 749.2 616.7 739.6 557.7 696.6 547.7 691.2 546.7 681 544.8 674.1 535 675.9 524.8 677.7 514.6 687.3 507.8 697.6 509.4 718.7 512.9 752.5 529.7 772.6 568.1 776.2 562.9 780.2 557.9 784.7 553 808.7 527.3 854.1 496.6 934 496.6ZM469 589.7C486.1 589.7 500 603.5 500 620.7 500 637.8 486.1 651.7 469 651.7 451.8 651.7 437.9 637.8 437.9 620.7 437.9 603.5 451.8 589.7 469 589.7ZM344.8 589.7C356 589.5 366.4 595.4 372.1 605 377.7 614.7 377.7 626.7 372.1 636.3 366.4 646 356 651.9 344.8 651.7L220.7 651.7C209.5 651.9 199.1 646 193.4 636.3 187.8 626.7 187.8 614.7 193.4 605 199.1 595.4 209.5 589.5 220.7 589.7ZM344.8 465.5C356 465.4 366.4 471.2 372.1 480.9 377.7 490.6 377.7 502.5 372.1 512.2 366.4 521.9 356 527.7 344.8 527.6L220.7 527.6C209.5 527.7 199.1 521.9 193.4 512.2 187.8 502.5 187.8 490.6 193.4 480.9 199.1 471.2 209.5 465.4 220.7 465.5ZM469 465.5C486.1 465.5 500 479.4 500 496.6 500 513.7 486.1 527.6 469 527.6 451.8 527.6 437.9 513.7 437.9 496.6 437.9 479.4 451.8 465.5 469 465.5ZM469 341.4C486.1 341.4 500 355.3 500 372.4 500 389.6 486.1 403.4 469 403.4 451.8 403.4 437.9 389.6 437.9 372.4 437.9 355.3 451.8 341.4 469 341.4ZM344.8 341.4C356 341.2 366.4 347.1 372.1 356.8 377.7 366.4 377.7 378.4 372.1 388.1 366.4 397.7 356 403.6 344.8 403.4L220.7 403.4C209.5 403.6 199.1 397.7 193.4 388.1 187.8 378.4 187.8 366.4 193.4 356.8 199.1 347.1 209.5 341.2 220.7 341.4ZM344.8 62.1C327.3 62.1 313.8 75.6 313.8 93.1 313.8 110.6 327.3 124.1 344.8 124.1 362.3 124.1 375.9 110.6 375.9 93.1 375.9 75.6 362.3 62.1 344.8 62.1Z", + "width": 1000 + }, + "search": [ + "nutritional_facts" + ] + }, + { + "uid": "fb91e50a0a60ee715526323e05dc49fe", + "css": "vibration", + "code": 59435, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M307.7 83.3C265.2 83.3 230.8 117.8 230.8 160.3L230.8 852.6C230.8 895.1 265.2 929.5 307.7 929.5L692.3 929.5C734.8 929.5 769.2 895.1 769.2 852.6L769.2 160.3C769.2 117.8 734.8 83.3 692.3 83.3L307.7 83.3ZM307.7 198.7L692.3 198.7 692.3 814.1 307.7 814.1 307.7 198.7ZM21.7 275.6C16.1 275.6 10.6 277.8 6.6 282.2-2.2 291-2.2 304.9 6.6 313L101.1 407.5 6.6 502C-2.2 510.8-2.2 524.7 6.6 532.8L101.1 627.3 6.6 721.8C-2.2 730.6-2.2 743.8 6.6 752.6 11 757 16.8 759.2 22 759.2 27.1 759.2 33 757 37.4 752.6L147.2 642.7C156 633.9 156 620 147.2 611.9L52.7 517.4 147.2 422.9C156 414.1 156 400.2 147.2 392.1L37.4 282.2C33 277.8 27.3 275.6 21.7 275.6ZM977.8 275.6C972.2 275.6 966.7 277.8 962.6 282.2L852.8 392.1C844 400.9 844 414.8 852.8 422.9L947.3 517.4 852.8 611.9C844 620.7 844 634.6 852.8 642.7L962.6 752.6C967 757 972.9 759.2 978 759.2 983.2 759.2 989 757 993.4 752.6 1002.2 743.8 1002.2 729.9 993.4 721.8L898.9 627.3 993.4 532.8C1002.2 524 1002.2 510.8 993.4 502L898.9 407.5 993.4 313C1002.2 304.2 1002.2 290.3 993.4 282.2 989 277.8 983.3 275.6 977.8 275.6Z", + "width": 1000 + }, + "search": [ + "vibration" + ] + }, + { + "uid": "d76ee24515af3c2cbe9fafab4de44204", + "css": "programming", + "code": 59436, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M90.9 47.4C40.7 47.4 0 88.1 0 138.3L0 683.7C0 734 40.7 774.6 90.9 774.6L409.1 774.6 409.1 865.6 318.2 865.6 318.2 956.5 681.8 956.5 681.8 865.6 590.9 865.6 590.9 774.6 909.1 774.6C959.3 774.6 1000 734 1000 683.7L1000 138.3C1000 88.1 959.3 47.4 909.1 47.4L90.9 47.4ZM90.9 138.3L909.1 138.3 909.1 683.7 90.9 683.7 90.9 138.3ZM512.3 220.9L421.4 584.6 487.7 601.1 578.6 237.4 512.3 220.9ZM327.6 265.2L181.8 411 327.6 556.8 373 511.3 272.7 411 373 310.7 327.6 265.2ZM672.4 265.2L627 310.7 727.3 411 627 511.3 672.4 556.8 818.2 411 672.4 265.2Z", + "width": 1000 + }, + "search": [ + "programming" + ] + }, + { + "uid": "c52b33e35825a8e8037a90d3b6b646c2", + "css": "country", + "code": 59482, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500 0C337.1 0 192.4 78.9 101.1 200L100 200 100 201.4C37.5 284.8 0 388 0 500 0 775.6 224.4 1000 500 1000 775.6 1000 1000 775.6 1000 500 1000 224.4 775.6 0 500 0ZM650 129.2C796.8 188.4 900 331.6 900 500 900 604.4 860 698.9 794.9 770 782.1 729.5 744.7 700 700 700 672.4 700 650 677.6 650 650L650 550C650 522.4 627.6 500 600 500L400 500C372.4 500 350 477.6 350 450 350 422.4 372.4 400 400 400 427.6 400 450 377.6 450 350L450 300C450 272.4 472.4 250 500 250L550 250C605.3 250 650 205.3 650 150L650 129.2ZM110.4 410.4L350 650 350 700C350 755.3 394.8 800 450 800L450 896.6C252.3 872.1 100 704.5 100 500 100 469.1 103.8 439.2 110.4 410.4Z", + "width": 1000 + }, + "search": [ + "country" + ] + }, + { + "uid": "3ce590f4efc2e583af54473012e125bf", + "css": "hamburger_menu", + "code": 59484, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M286.7 366.7C279.6 366.6 272.9 370.3 269.4 376.4 265.8 382.6 265.8 390.2 269.4 396.3 272.9 402.5 279.6 406.2 286.7 406.1L681 406.1C688.1 406.2 694.7 402.5 698.3 396.3 701.8 390.2 701.8 382.6 698.3 376.4 694.7 370.3 688.1 366.6 681 366.7L286.7 366.7ZM286.7 465.2C279.6 465.1 272.9 468.9 269.4 475 265.8 481.2 265.8 488.8 269.4 494.9 272.9 501 279.6 504.8 286.7 504.7L681 504.7C688.1 504.8 694.7 501 698.3 494.9 701.8 488.8 701.8 481.2 698.3 475 694.7 468.9 688.1 465.1 681 465.2L286.7 465.2ZM286.7 563.8C279.6 563.7 272.9 567.4 269.4 573.6 265.8 579.7 265.8 587.3 269.4 593.5 272.9 599.6 279.6 603.3 286.7 603.2L681 603.2C688.1 603.3 694.7 599.6 698.3 593.5 701.8 587.3 701.8 579.7 698.3 573.6 694.7 567.4 688.1 563.7 681 563.8L286.7 563.8Z", + "width": 1000 + }, + "search": [ + "hamburger_menu" + ] + }, + { + "uid": "5cf1541a6d6b001cecc06fbc4c40d560", + "css": "password", + "code": 59485, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500 0C341.7 0 214.3 127.4 214.3 285.7L214.3 333.3C161.9 333.3 119 376.2 119 428.6L119 904.8C119 957.1 161.9 1000 214.3 1000L785.7 1000C838.1 1000 881 957.1 881 904.8L881 428.6C881 376.2 838.1 333.3 785.7 333.3L785.7 285.7C785.7 127.4 658.3 0 500 0ZM500 95.2C608.4 95.2 690.5 177.3 690.5 285.7L690.5 333.3 309.5 333.3 309.5 285.7C309.5 177.3 391.6 95.2 500 95.2ZM309.5 619C335.7 619 357.1 640.5 357.1 666.7 357.1 692.9 335.7 714.3 309.5 714.3 283.3 714.3 261.9 692.9 261.9 666.7 261.9 640.5 283.3 619 309.5 619ZM500 619C526.2 619 547.6 640.5 547.6 666.7 547.6 692.9 526.2 714.3 500 714.3 473.8 714.3 452.4 692.9 452.4 666.7 452.4 640.5 473.8 619 500 619ZM690.5 619C716.7 619 738.1 640.5 738.1 666.7 738.1 692.9 716.7 714.3 690.5 714.3 664.3 714.3 642.9 692.9 642.9 666.7 642.9 640.5 664.3 619 690.5 619Z", + "width": 1000 + }, + "search": [ + "password" + ] + }, + { + "uid": "e4b4441dfd75207565ba52d57153f80b", + "css": "incognito", + "code": 59486, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M369 0C272.8 0 226.9 195.6 192.3 334.1 192.3 335 193.5 335.6 193.5 336.5 76.3 361.2 0 399.2 0 442.3 0 475.1 45.5 504.4 117.8 527.6 116.1 535.2 115.4 542.5 115.4 550.5 115.4 579.9 124.7 608.2 140.6 634.6 143 638.7 146 642.7 149 646.6 117.2 663.8 58 703.1 0 784.9L161.1 907.5 146.6 1000 858.2 1000 838.9 907.5 1000 784.9C942.6 703.9 884.3 664.1 852.2 646.6 854.4 643.6 856.2 640.2 858.2 637 874.4 610.7 884.6 581 884.6 550.5 884.6 542.7 883.6 535 882.2 527.6 954.5 504.4 1000 475.1 1000 442.3 1000 399.3 924.1 361.2 807.7 336.5 807.7 335.8 807.7 334.9 807.7 334.1 765.3 188 727.2 0 631 0 581 0 553.8 19.2 500 19.2 446.2 19.2 422.8 0 369 0ZM192.3 548.1C277.3 566.1 383.4 576.9 500 576.9 616.6 576.9 722.7 566.1 807.7 548.1 807.8 549.4 807.7 547.9 807.7 550.5 807.7 562.3 802 582 793.3 596.2 784.6 610.3 774.2 615.2 772.8 615.4 758.6 617.2 746.4 627 741.6 640.6 713.3 713.9 678.2 787.3 637 840.1 595.9 893 552.3 923.1 500 923.1 448.5 923.1 403.5 891.7 361.8 837.7 320 783.8 285.8 709.9 259.6 640.6 254.5 626.7 241.9 616.9 227.2 615.4 227.2 615.4 215.7 609.8 206.7 595 197.7 580.1 192.3 559.5 192.3 550.5 192.3 549.1 192.3 549.1 192.3 548.1ZM359.4 578.1C326.9 577.1 307.7 582.2 307.7 608.2 307.7 654.3 338.9 700.4 396.6 704.3 435.1 708.2 480.8 684.8 480.8 631 480.8 592.5 450.4 584.4 396.6 580.5 383.1 579.6 370.2 578.4 359.4 578.1ZM640.6 578.1C629.8 578.4 616.9 579.6 603.4 580.5 549.6 584.4 519.2 592.5 519.2 631 519.2 684.8 564.9 708.2 603.4 704.3 661.1 700.4 692.3 654.3 692.3 608.2 692.3 582.2 673.1 577.1 640.6 578.1Z", + "width": 1000 + }, + "search": [ + "incognito" + ] + }, + { + "uid": "8b9b70446a65668da68c2844d30ce64d", + "css": "logout", + "code": 59487, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M888.9 0L111.1 0C49.7 0 0 49.7 0 111.1L0 888.9C0 950.3 49.7 1000 111.1 1000L888.9 1000C950.3 1000 1000 950.3 1000 888.9L1000 111.1C1000 49.7 950.3 0 888.9 0ZM928.2 539.3L744.8 722.6C734 733.4 719.8 738.9 705.6 738.9 691.3 738.9 677.1 733.4 666.3 722.6 644.6 700.9 644.6 665.8 666.3 644.1L754.8 555.6 333.3 555.6C302.6 555.6 277.8 530.7 277.8 500 277.8 469.3 302.6 444.4 333.3 444.4L754.8 444.4 666.3 355.9C644.6 334.2 644.6 299.1 666.3 277.4 688 255.7 723.1 255.7 744.8 277.4L928.2 460.7C949.9 482.4 949.9 517.6 928.2 539.3Z", + "width": 1000 + }, + "search": [ + "logout" + ] + }, + { + "uid": "0a8c4734a2d9171bf040a5cbd4b019a2", + "css": "donate", + "code": 59489, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M800 0C720 0 675 55 675 55 675 55 630 0 550 0 465 0 400 70 400 150 400 275 675 495 675 495 675 495 950 275 950 150 950 70 880 0 800 0ZM900 500L650 750 450 750 450 700 650 700 650 550 250 550 0 800 200 1000 300 900 660 900C685 900 710 890 730 870L1000 600 900 500Z", + "width": 1000 + }, + "search": [ + "donate" + ] + }, + { + "uid": "21ec239b566a930a77613e0015a4661c", + "css": "dangerous_zone", + "code": 59490, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M238.1 22.7C185.5 22.7 142.9 66.9 142.9 121.3 142.9 175.7 185.5 219.9 238.1 219.9 290.7 219.9 333.3 175.7 333.3 121.3 333.3 66.9 290.7 22.7 238.1 22.7ZM761.9 22.7C709.3 22.7 666.7 66.9 666.7 121.3 666.7 175.7 709.3 219.9 761.9 219.9 814.5 219.9 857.1 175.7 857.1 121.3 857.1 66.9 814.5 22.7 761.9 22.7ZM107.1 269.2C48.4 269.2 0 319.3 0 380.1L0 527.9C0 588.7 48.4 638.8 107.1 638.8L166.7 638.8 166.7 792.9C166 796.9 166 801 166.7 804.9L166.7 946.9C166.5 960.2 173.3 972.6 184.4 979.3 195.5 986 209.3 986 220.4 979.3 231.5 972.6 238.3 960.2 238.1 946.9L238.1 836 761.9 836 761.9 946.9C761.7 960.2 768.5 972.6 779.6 979.3 790.7 986 804.5 986 815.6 979.3 826.7 972.6 833.5 960.2 833.3 946.9L833.3 805.1C834 801.1 834 797.1 833.3 793.1L833.3 638.8 892.9 638.8C951.6 638.8 1000 588.7 1000 527.9L1000 380.1C1000 319.3 951.6 269.2 892.9 269.2L107.1 269.2ZM107.1 343.1L211.5 343.1 89.2 559.9C78.5 553.7 71.4 541.9 71.4 527.9L71.4 380.1C71.4 359.2 87 343.1 107.1 343.1ZM365.9 343.1L485.4 343.1 360.3 564.9 240.8 564.9 365.9 343.1ZM639.7 343.1L759.2 343.1 634.1 564.9 514.6 564.9 639.7 343.1ZM910.8 348.1C921.5 354.3 928.6 366.1 928.6 380.1L928.6 527.9C928.6 548.8 913 564.9 892.9 564.9L803.5 564.9C799.6 564.2 795.7 564.2 791.9 564.9L788.5 564.9 910.8 348.1ZM238.1 638.8L761.9 638.8 761.9 762 238.1 762 238.1 638.8Z", + "width": 1000 + }, + "search": [ + "dangerous_zone" + ] + }, + { + "uid": "1516825d06c15eda357b9a86684a2aca", + "css": "happy_toast", + "code": 59491, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M493.9 66.8C376.9 65.4 262.2 74.7 150.7 95.5 53.6 113.7 0 173 0 262.2 0 327.7 36.6 386.4 90.9 413.7L90.9 793.5C90.9 868.6 152.1 929.8 227.3 929.8L272.7 929.8 727.3 929.8 772.7 929.8C847.9 929.8 909.1 868.6 909.1 793.5L909.1 413.7C963.4 386.4 1000 327.8 1000 262.3 1000 204.6 974.5 129 848.6 95.4 728.6 74.7 610.1 65.4 493.9 66.8ZM363.6 429.8C388.7 429.8 409.1 450.2 409.1 475.3 409.1 500.4 388.7 520.7 363.6 520.7 338.5 520.7 318.2 500.4 318.2 475.3 318.2 450.2 338.5 429.8 363.6 429.8ZM681.8 429.8C706.9 429.8 727.3 450.2 727.3 475.3 727.3 500.4 706.9 520.7 681.8 520.7 656.7 520.7 636.4 500.4 636.4 475.3 636.4 450.2 656.7 429.8 681.8 429.8ZM409.1 611.6L636.4 611.6C636.4 661.9 585.5 702.6 522.7 702.6 460 702.6 409.1 661.9 409.1 611.6Z", + "width": 1000 + }, + "search": [ + "happy_toast" + ] + }, + { + "uid": "7c609c9cd136746313d773004824e4cb", + "css": "light_bulb", + "code": 59492, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500 20.8C477 20.8 458.3 39.5 458.3 62.5 458.3 85.5 477 104.2 500 104.2 523 104.2 541.7 85.5 541.7 62.5 541.7 39.5 523 20.8 500 20.8ZM175.9 155.1C152.9 155.1 134.3 173.8 134.3 196.8 134.3 219.8 152.9 238.4 175.9 238.4 199 238.4 217.6 219.8 217.6 196.8 217.6 173.8 199 155.1 175.9 155.1ZM824.1 155.1C801 155.1 782.4 173.8 782.4 196.8 782.4 219.8 801 238.4 824.1 238.4 847.1 238.4 865.7 219.8 865.7 196.8 865.7 173.8 847.1 155.1 824.1 155.1ZM500 229.2C339.2 229.2 208.3 360 208.3 520.8 208.3 636.9 276.6 737 375 783.9L375 895.8C375 941.8 412.4 979.2 458.3 979.2L541.7 979.2C587.6 979.2 625 941.8 625 895.8L625 783.9C723.4 737 791.7 636.9 791.7 520.8 791.7 360 660.8 229.2 500 229.2ZM41.7 479.2C18.7 479.2 0 497.8 0 520.8 0 543.8 18.7 562.5 41.7 562.5 64.7 562.5 83.3 543.8 83.3 520.8 83.3 497.8 64.7 479.2 41.7 479.2ZM958.3 479.2C935.3 479.2 916.7 497.8 916.7 520.8 916.7 543.8 935.3 562.5 958.3 562.5 981.3 562.5 1000 543.8 1000 520.8 1000 497.8 981.3 479.2 958.3 479.2ZM175.9 803.2C152.9 803.2 134.3 821.9 134.3 844.9 134.3 867.9 152.9 886.6 175.9 886.6 199 886.6 217.6 867.9 217.6 844.9 217.6 821.9 199 803.2 175.9 803.2ZM824.1 803.2C801 803.2 782.4 821.9 782.4 844.9 782.4 867.9 801 886.6 824.1 886.6 847.1 886.6 865.7 867.9 865.7 844.9 865.7 821.9 847.1 803.2 824.1 803.2Z", + "width": 1000 + }, + "search": [ + "light_bulb" + ] + }, + { + "uid": "803e7701e3919809f716843644e1d368", + "css": "ingredients_basket", + "code": 59472, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M615.4 19.3C594.2 19.3 576.9 36.5 576.9 57.8 576.9 71.8 584.8 83.5 595.9 90.2L532.9 195.2C511.4 231.1 500 272.2 500 314L500 327 846.2 327 846.2 314C846.2 272.2 834.8 231.1 813.3 195.2L750.2 90.2C761.4 83.5 769.2 71.8 769.2 57.8 769.2 36.5 752 19.3 730.8 19.3L615.4 19.3ZM403.8 134.7C371.6 134.7 342.5 146.5 319.3 165.4L432.4 240.8C439.7 211 451 182.2 466.9 155.7L469 152.2C449.6 141.4 427.6 134.7 403.8 134.7ZM213.9 191.9C197.4 189.4 180.2 197.4 172.2 213.4L115.4 327 423.1 327 229.8 198.1C224.8 194.8 219.4 192.8 213.9 191.9ZM38.5 403.9C17.2 403.9 0 421.2 0 442.4L0 519.3C0 540.5 17.2 557.8 38.5 557.8L44.8 557.8 104.6 916.6C110.8 953.6 142.9 980.9 180.5 980.9L819.4 980.9C857 980.9 889.1 953.6 895.3 916.6L955.2 557.8 961.5 557.8C982.8 557.8 1000 540.5 1000 519.3L1000 442.4C1000 421.2 982.8 403.9 961.5 403.9L38.5 403.9ZM346.2 557.8C367.4 557.8 384.6 575 384.6 596.2L384.6 827C384.6 848.3 367.4 865.5 346.2 865.5 324.9 865.5 307.7 848.3 307.7 827L307.7 596.2C307.7 575 324.9 557.8 346.2 557.8ZM500 557.8C521.3 557.8 538.5 575 538.5 596.2L538.5 827C538.5 848.3 521.3 865.5 500 865.5 478.7 865.5 461.5 848.3 461.5 827L461.5 596.2C461.5 575 478.7 557.8 500 557.8ZM653.8 557.8C675.1 557.8 692.3 575 692.3 596.2L692.3 827C692.3 848.3 675.1 865.5 653.8 865.5 632.6 865.5 615.4 848.3 615.4 827L615.4 596.2C615.4 575 632.6 557.8 653.8 557.8Z", + "width": 1000 + }, + "search": [ + "ingredients_basket" + ] + }, + { + "uid": "9b5d9d7ce43b4e7938e0ccfe212bc6da", + "css": "github", + "code": 59471, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500 7.7C223.9 7.7 0 231.6 0 507.7 0 742 161.3 938.1 378.8 992.3 376.5 985.6 375 977.7 375 968L375 882.6C354.7 882.6 320.7 882.6 312.2 882.6 278 882.6 247.5 867.9 232.8 840.5 216.4 810.1 213.6 763.7 173 735.3 161 725.8 170.1 715 184 716.5 209.6 723.7 230.9 741.3 250.9 767.4 270.8 793.5 280.2 799.4 317.4 799.4 335.4 799.4 362.4 798.4 387.8 794.4 401.5 759.7 425.1 727.7 454 712.6 287.5 695.5 208 612.7 208 500.2 208 451.8 228.7 405 263.7 365.5 252.2 326.4 237.8 246.5 268.1 216.1 343 216.1 388.3 264.6 399.2 277.8 436.5 265 477.5 257.7 520.6 257.7 563.8 257.7 605 265 642.4 277.9 653.1 264.8 698.5 216.1 773.5 216.1 804 246.5 789.4 326.7 777.8 365.8 812.6 405.2 833.1 451.9 833.1 500.2 833.1 612.6 753.8 695.4 587.5 712.6 633.3 736.5 666.7 803.6 666.7 854.1L666.7 968C666.7 972.4 665.7 975.5 665.2 979.2 860 910.9 1000 725.9 1000 507.7 1000 231.6 776.1 7.7 500 7.7Z", + "width": 1000 + }, + "search": [ + "github" + ] + }, + { + "uid": "7fc010266ac51486305f36d0be15936e", + "css": "document", + "code": 59470, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M223.6 0C161.5 0 111.1 50.4 111.1 112.5L111.1 887.5C111.1 949.6 161.5 1000 223.6 1000L798.6 1000C860.7 1000 911.1 949.6 911.1 887.5L911.1 400 623.6 400C561.5 400 511.1 349.6 511.1 287.5L511.1 0 223.6 0ZM586.1 22L586.1 287.5C586.1 308.2 602.9 325 623.6 325L889.1 325 586.1 22ZM323.6 500C358.1 500 386.1 528 386.1 562.5 386.1 597 358.1 625 323.6 625 289.1 625 261.1 597 261.1 562.5 261.1 528 289.1 500 323.6 500ZM498.6 525L723.6 525C744.3 525 761.1 541.8 761.1 562.5 761.1 583.2 744.3 600 723.6 600L498.6 600C477.9 600 461.1 583.2 461.1 562.5 461.1 541.8 477.9 525 498.6 525ZM323.6 700C358.1 700 386.1 728 386.1 762.5 386.1 797 358.1 825 323.6 825 289.1 825 261.1 797 261.1 762.5 261.1 728 289.1 700 323.6 700ZM498.6 725L723.6 725C744.3 725 761.1 741.8 761.1 762.5 761.1 783.2 744.3 800 723.6 800L498.6 800C477.9 800 461.1 783.2 461.1 762.5 461.1 741.8 477.9 725 498.6 725Z", + "width": 1000 + }, + "search": [ + "document" + ] + }, + { + "uid": "fbcb7a1dae0e327f0e00acd80ec3ed2e", + "css": "app_store", + "code": 59469, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M400 25C345.3 25 300 70.3 300 125L300 225 0 225 0 825C0 907.7 67.3 975 150 975L850 975C932.7 975 1000 907.7 1000 825L1000 225 700 225 700 125C700 70.3 654.7 25 600 25L400 25ZM400 125L600 125 600 225 400 225 400 125ZM350 400L700 600 350 800 350 400Z", + "width": 1000 + }, + "search": [ + "app_store" + ] + }, + { + "uid": "ca5b037f223ac7e19f8746372b14dac0", + "css": "language_world", + "code": 59493, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M500 0C224.2 0 0 224.2 0 500 0 775.6 223.9 999.7 499.4 1000 499.6 1000 499.8 1000 500 1000 775.8 1000 1000 775.8 1000 500 1000 224.4 776.1 0.3 500.6 0 500.5 0 500.4 0 500.3 0 500.2 0 500.1 0 500 0L500 0ZM478.4 45.8L478.4 260.6C423.2 259.3 370.6 252.9 322 242.8 330.5 217 340.1 193 350.8 171.4 386.4 99.8 431.6 56.2 478.4 45.8ZM521.6 45.8C568.4 56.2 613.6 99.8 649.2 171.4 660.1 193.3 669.8 217.7 678.4 243.9 629.8 253.5 577 259.5 521.6 260.7L521.6 45.8ZM375.3 60.6C351.4 85.2 330 116 312 152.2 299.8 176.8 289.1 203.9 279.7 232.8 236.9 221.4 198.3 206.9 165.2 190 221.4 129.4 293.5 83.8 375.3 60.6ZM624.6 60.6C707 83.9 779.6 130 835.9 191.3 803.2 208.5 764.3 223.1 720.8 234.3 711.3 204.8 700.4 177.2 688 152.2 670 116 648.6 85.2 624.6 60.6ZM136.7 223.9C174.7 244.3 218.8 261.5 267.6 274.6 251.7 336.3 242.4 405.3 240.8 478.4L43.8 478.4C48.3 382.8 82.4 295.3 136.7 223.9ZM864.2 225.1C918 296.2 951.7 383.3 956.2 478.4L759.2 478.4C757.6 405.9 748.5 337.5 732.8 276.2 782.1 263.3 826.4 246.2 864.2 225.1ZM309.8 284.6C362.4 295.7 418.9 302.6 478.4 304L478.4 478.4 284.1 478.4C285.7 408.5 294.8 342.8 309.8 284.6ZM690.5 285.9C705.3 343.7 714.3 409 715.9 478.4L521.6 478.4 521.6 304.1C581.1 302.8 637.9 296.4 690.5 285.9ZM43.8 521.6L240.8 521.6C242.4 594.1 251.5 662.5 267.2 723.8 217.9 736.7 173.6 753.8 135.8 774.9 82 703.8 48.3 616.7 43.8 521.6ZM284.1 521.6L478.4 521.6 478.4 696C418.9 697.2 362.1 703.6 309.5 714.1 294.7 656.3 285.7 591 284.1 521.6ZM521.6 521.6L715.9 521.6C714.3 591.5 705.2 657.2 690.2 715.4 637.6 704.3 581.1 697.4 521.6 696L521.6 521.6ZM759.2 521.6L956.2 521.6C951.7 617.2 917.6 704.7 863.3 776.1 825.3 755.7 781.2 738.5 732.4 725.4 748.3 663.7 757.6 594.7 759.2 521.6ZM478.4 739.3L478.4 954.2C431.6 943.8 386.4 900.2 350.8 828.6 339.9 806.7 330.2 782.3 321.6 756.1 370.2 746.5 423 740.5 478.4 739.3ZM521.6 739.4C576.8 740.7 629.4 747.1 678 757.2 669.5 783 659.9 807 649.2 828.6 613.6 900.2 568.4 943.8 521.6 954.2L521.6 739.4ZM279.2 765.7C288.7 795.2 299.6 822.8 312 847.8 330 884 351.4 914.8 375.4 939.4 293 916.1 220.4 870 164.1 808.7 196.8 791.5 235.7 776.9 279.2 765.7ZM720.3 767.2C763.1 778.6 801.7 793.1 834.8 810 778.6 870.6 706.5 916.2 624.7 939.4 648.6 914.8 670 884 688 847.8 700.2 823.2 710.9 796.1 720.3 767.2Z", + "width": 1000 + }, + "search": [ + "language_world" + ] + }, + { + "uid": "f962c5948c9a5778918a258c70e2195a", + "css": "personalization_alt", + "code": 59494, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M400 0C334.9 0 279.9 41.9 259.2 100L0 100 0 200 259.2 200C279.9 258.1 334.9 300 400 300 482.7 300 550 232.7 550 150 550 67.3 482.7 0 400 0ZM650 100L650 200 1000 200 1000 100 650 100ZM650 350C584.9 350 529.9 391.9 509.2 450L0 450 0 550 509.2 550C529.9 608.1 584.9 650 650 650 732.7 650 800 582.7 800 500 800 417.3 732.7 350 650 350ZM900 450L900 550 1000 550 1000 450 900 450ZM250 700C184.9 700 129.9 741.9 109.2 800L0 800 0 900 109.2 900C129.9 958.1 184.9 1000 250 1000 332.7 1000 400 932.7 400 850 400 767.3 332.7 700 250 700ZM500 800L500 900 1000 900 1000 800 500 800Z", + "width": 1000 + }, + "search": [ + "personalization_alt" + ] } ] } \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/contribute.svg b/packages/smooth_app/assets/fonts/icons/contribute.svg new file mode 100644 index 000000000000..cf6162494b8f --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/contribute.svg @@ -0,0 +1,7 @@ + + + Contribute + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/country.svg b/packages/smooth_app/assets/fonts/icons/country.svg new file mode 100644 index 000000000000..995a08a19b6f --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/country.svg @@ -0,0 +1,7 @@ + + + Country + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/crash.svg b/packages/smooth_app/assets/fonts/icons/crash.svg new file mode 100644 index 000000000000..d9ff11bf1ec4 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/crash.svg @@ -0,0 +1,7 @@ + + + Crash + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/currency.svg b/packages/smooth_app/assets/fonts/icons/currency.svg new file mode 100644 index 000000000000..8f9d453a4974 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/currency.svg @@ -0,0 +1,7 @@ + + + Currency + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/dangerous_zone.svg b/packages/smooth_app/assets/fonts/icons/dangerous_zone.svg new file mode 100644 index 000000000000..5ecb924136c3 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/dangerous_zone.svg @@ -0,0 +1,7 @@ + + + danger zone + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/delete_trash.svg b/packages/smooth_app/assets/fonts/icons/delete_trash.svg new file mode 100644 index 000000000000..64a59a2c08f5 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/delete_trash.svg @@ -0,0 +1,7 @@ + + + Trash delete + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/document.svg b/packages/smooth_app/assets/fonts/icons/document.svg new file mode 100644 index 000000000000..63b684c27525 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/document.svg @@ -0,0 +1,7 @@ + + + Document + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/donate.svg b/packages/smooth_app/assets/fonts/icons/donate.svg new file mode 100644 index 000000000000..c096702c0ec8 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/donate.svg @@ -0,0 +1,7 @@ + + + programming + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/eye_invisible.svg b/packages/smooth_app/assets/fonts/icons/eye_invisible.svg new file mode 100644 index 000000000000..876a5bbf8618 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/eye_invisible.svg @@ -0,0 +1,7 @@ + + + Invisible (eye) + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/eye_visible.svg b/packages/smooth_app/assets/fonts/icons/eye_visible.svg new file mode 100644 index 000000000000..f37cebf7b573 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/eye_visible.svg @@ -0,0 +1,7 @@ + + + Visible (eye) + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/github.svg b/packages/smooth_app/assets/fonts/icons/github.svg new file mode 100644 index 000000000000..0b3882f01e79 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/github.svg @@ -0,0 +1,7 @@ + + + github + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/hamburger_menu.svg b/packages/smooth_app/assets/fonts/icons/hamburger_menu.svg new file mode 100644 index 000000000000..f0b7fe79c19e --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/hamburger_menu.svg @@ -0,0 +1,7 @@ + + + Hamburger menu + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/happy_toast.svg b/packages/smooth_app/assets/fonts/icons/happy_toast.svg new file mode 100644 index 000000000000..6ef0398295e2 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/happy_toast.svg @@ -0,0 +1,7 @@ + + + Happy toast + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/icons.sketch b/packages/smooth_app/assets/fonts/icons/icons.sketch index 317f26f166a5..14a322096d39 100644 Binary files a/packages/smooth_app/assets/fonts/icons/icons.sketch and b/packages/smooth_app/assets/fonts/icons/icons.sketch differ diff --git a/packages/smooth_app/assets/fonts/icons/image_add.svg b/packages/smooth_app/assets/fonts/icons/image_add.svg new file mode 100644 index 000000000000..879719436748 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/image_add.svg @@ -0,0 +1,7 @@ + + + Image add + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/image_check.svg b/packages/smooth_app/assets/fonts/icons/image_check.svg new file mode 100644 index 000000000000..c84ce8140c2d --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/image_check.svg @@ -0,0 +1,8 @@ + + + Image check + + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/incognito.svg b/packages/smooth_app/assets/fonts/icons/incognito.svg new file mode 100644 index 000000000000..bd8352395b47 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/incognito.svg @@ -0,0 +1,7 @@ + + + Incognito + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/ingredients_basket.svg b/packages/smooth_app/assets/fonts/icons/ingredients_basket.svg new file mode 100644 index 000000000000..cf2b5680fe5e --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/ingredients_basket.svg @@ -0,0 +1,7 @@ + + + Ingredients basket + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/language.svg b/packages/smooth_app/assets/fonts/icons/language.svg new file mode 100644 index 000000000000..ba1f6684fcbf --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/language.svg @@ -0,0 +1,7 @@ + + + Language + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/language_world.svg b/packages/smooth_app/assets/fonts/icons/language_world.svg new file mode 100644 index 000000000000..3716f26c92cc --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/language_world.svg @@ -0,0 +1,7 @@ + + + Language (world) + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/light_bulb.svg b/packages/smooth_app/assets/fonts/icons/light_bulb.svg new file mode 100644 index 000000000000..143107fb8c19 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/light_bulb.svg @@ -0,0 +1,7 @@ + + + Light bulb + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/logout.svg b/packages/smooth_app/assets/fonts/icons/logout.svg new file mode 100644 index 000000000000..dd7d9cb5c8cb --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/logout.svg @@ -0,0 +1,7 @@ + + + Logout + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/nutritional_facts.svg b/packages/smooth_app/assets/fonts/icons/nutritional_facts.svg new file mode 100644 index 000000000000..33871bdb189c --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/nutritional_facts.svg @@ -0,0 +1,7 @@ + + + Nutritional facts + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/password.svg b/packages/smooth_app/assets/fonts/icons/password.svg new file mode 100644 index 000000000000..768147e4ba83 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/password.svg @@ -0,0 +1,7 @@ + + + Password + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/personalization_alt.svg b/packages/smooth_app/assets/fonts/icons/personalization_alt.svg new file mode 100644 index 000000000000..efcd54623af2 --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/personalization_alt.svg @@ -0,0 +1,7 @@ + + + Personalization alt + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/programming.svg b/packages/smooth_app/assets/fonts/icons/programming.svg new file mode 100644 index 000000000000..2a46cc5d99cc --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/programming.svg @@ -0,0 +1,7 @@ + + + programming + + + + \ No newline at end of file diff --git a/packages/smooth_app/assets/fonts/icons/vibration.svg b/packages/smooth_app/assets/fonts/icons/vibration.svg new file mode 100644 index 000000000000..e3d79978db9e --- /dev/null +++ b/packages/smooth_app/assets/fonts/icons/vibration.svg @@ -0,0 +1,7 @@ + + + Vibration + + + + \ No newline at end of file diff --git a/packages/smooth_app/ios/Podfile.lock b/packages/smooth_app/ios/Podfile.lock index ba40bf624b91..2f89895cc3a8 100644 --- a/packages/smooth_app/ios/Podfile.lock +++ b/packages/smooth_app/ios/Podfile.lock @@ -310,4 +310,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: e840dd57ba2b03bcb6fdba293a27c5f82151a80a -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/packages/smooth_app/lib/cards/product_cards/smooth_product_card_found.dart b/packages/smooth_app/lib/cards/product_cards/smooth_product_card_found.dart index cf201e5ab752..7a758ebac626 100644 --- a/packages/smooth_app/lib/cards/product_cards/smooth_product_card_found.dart +++ b/packages/smooth_app/lib/cards/product_cards/smooth_product_card_found.dart @@ -114,7 +114,7 @@ class SmoothProductCardFound extends StatelessWidget { Icon( Icons.circle, size: 15, - color: helper.getButtonColor(isDarkMode), + color: helper.getColor(context), ), const Padding( padding: EdgeInsetsDirectional.only( diff --git a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_bottom_sheet.dart b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_bottom_sheet.dart index 07b86f0722c0..7263078f3280 100644 --- a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_bottom_sheet.dart +++ b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_bottom_sheet.dart @@ -32,14 +32,20 @@ Future showSmoothDraggableModalSheet({ /// You must return a Sliver Widget required WidgetBuilder bodyBuilder, double? initHeight, + double? minHeight, + double? maxHeight, + DraggableScrollableController? draggableScrollableController, }) { return showDraggableModalSheet( context: context, + draggableScrollableController: draggableScrollableController, borderRadius: const BorderRadius.vertical(top: ROUNDED_RADIUS), headerBuilder: (_) => header, headerHeight: header.computeHeight(context), bodyBuilder: bodyBuilder, initHeight: initHeight, + minHeight: minHeight, + maxHeight: maxHeight, ); } @@ -98,7 +104,7 @@ class SmoothModalSheetHeader extends StatelessWidget implements SizeWidget { this.backgroundColor, }); - static const double MIN_HEIGHT = 50.0; + static const double MIN_HEIGHT = 55.0; final String title; final SizeWidget? prefix; @@ -108,13 +114,15 @@ class SmoothModalSheetHeader extends StatelessWidget implements SizeWidget { @override Widget build(BuildContext context) { - final Color primaryColor = Theme.of(context).primaryColor; + final Color primaryColor = + Theme.of(context).extension()!.primaryDark; + final Color tintColor = foregroundColor ?? Colors.white; return IconTheme( - data: IconThemeData(color: foregroundColor), + data: IconThemeData(color: tintColor), child: Container( height: suffix is SmoothModalSheetHeaderButton ? double.infinity : null, - color: backgroundColor ?? primaryColor.withOpacity(0.2), + color: backgroundColor ?? primaryColor, constraints: const BoxConstraints(minHeight: MIN_HEIGHT), padding: EdgeInsetsDirectional.only( start: (prefix?.requiresPadding == true ? 0 : VERY_LARGE_SPACE), @@ -143,7 +151,7 @@ class SmoothModalSheetHeader extends StatelessWidget implements SizeWidget { style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, fontSize: 18.0, - color: foregroundColor, + color: tintColor, ), ), ), @@ -266,29 +274,55 @@ class SmoothModalSheetHeaderCloseButton extends StatelessWidget const SmoothModalSheetHeaderCloseButton({ this.semanticsOrder, this.addPadding, + this.circled = true, }); final double? semanticsOrder; final bool? addPadding; + final bool circled; @override Widget build(BuildContext context) { + final Widget icon; + + if (circled == true) { + icon = Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: IconTheme.of(context).color ?? Colors.white, + width: 1.5, + ), + ), + margin: const EdgeInsets.all(VERY_SMALL_SPACE), + padding: const EdgeInsets.all(SMALL_SPACE), + child: const icons.Close( + size: 13.0, + ), + ); + } else { + icon = const Padding( + padding: EdgeInsets.all(MEDIUM_SPACE), + child: icons.Close( + size: 15.0, + ), + ); + } + return Semantics( value: MaterialLocalizations.of(context).closeButtonTooltip, button: true, excludeSemantics: true, sortKey: OrdinalSortKey(semanticsOrder ?? 2.0), - child: Tooltip( - message: MaterialLocalizations.of(context).closeButtonTooltip, - enableFeedback: true, - child: InkWell( - onTap: () => Navigator.of(context).pop(), - customBorder: const CircleBorder(), - child: const Padding( - padding: EdgeInsets.all(MEDIUM_SPACE), - child: icons.Close( - size: 15.0, - ), + child: Padding( + padding: const EdgeInsetsDirectional.only(end: SMALL_SPACE), + child: Tooltip( + message: MaterialLocalizations.of(context).closeButtonTooltip, + enableFeedback: true, + child: InkWell( + onTap: () => Navigator.of(context).pop(), + customBorder: const CircleBorder(), + child: icon, ), ), ), diff --git a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet.dart b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet.dart index 9d1b0790887c..6cae831cf8b8 100644 --- a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet.dart +++ b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet.dart @@ -10,6 +10,7 @@ class SmoothDraggableBottomSheet extends StatefulWidget { required this.bodyBuilder, required this.borderRadius, this.initHeightFraction = 0.5, + this.minHeightFraction, this.maxHeightFraction = 1.0, this.animationController, this.bottomSheetColor, @@ -17,6 +18,7 @@ class SmoothDraggableBottomSheet extends StatefulWidget { }) : assert(maxHeightFraction > 0.0 && maxHeightFraction <= 1.0); final double initHeightFraction; + final double? minHeightFraction; final double maxHeightFraction; final WidgetBuilder headerBuilder; final double headerHeight; @@ -52,55 +54,63 @@ class SmoothDraggableBottomSheetState Theme.of(context).scaffoldBackgroundColor; final double bottomPaddingHeight = MediaQuery.paddingOf(context).bottom; - return NotificationListener( - onNotification: _scrolling, - child: Column( - children: [ - Expanded( - child: SafeArea( - bottom: false, - child: DraggableScrollableSheet( - minChildSize: 0.0, - maxChildSize: widget.maxHeightFraction, - initialChildSize: widget.initHeightFraction, - snap: true, - controller: _controller, - builder: (BuildContext context, ScrollController controller) { - return DecoratedBox( - decoration: BoxDecoration( - borderRadius: widget.borderRadius, - color: backgroundColor, - ), - child: Material( - type: MaterialType.transparency, - child: ClipRRect( + // Fix keyboard glitch + final double keyboardFraction = MediaQuery.viewInsetsOf(context).bottom / + MediaQuery.sizeOf(context).height; + + return ChangeNotifierProvider( + create: (_) => _controller, + child: NotificationListener( + onNotification: _scrolling, + child: Column( + children: [ + Expanded( + child: SafeArea( + bottom: false, + child: DraggableScrollableSheet( + minChildSize: widget.minHeightFraction ?? 0.0, + maxChildSize: widget.maxHeightFraction, + initialChildSize: + widget.initHeightFraction + keyboardFraction, + snap: true, + controller: _controller, + builder: (BuildContext context, ScrollController controller) { + return DecoratedBox( + decoration: BoxDecoration( borderRadius: widget.borderRadius, - child: _SmoothDraggableContent( - bodyBuilder: widget.bodyBuilder, - headerBuilder: widget.headerBuilder, - headerHeight: widget.headerHeight, - currentExtent: _controller.isAttached - ? _controller.size - : widget.initHeightFraction, - scrollController: controller, - cacheExtent: _calculateCacheExtent( - MediaQuery.viewInsetsOf(context).bottom, + color: backgroundColor, + ), + child: Material( + type: MaterialType.transparency, + child: ClipRRect( + borderRadius: widget.borderRadius, + child: _SmoothDraggableContent( + bodyBuilder: widget.bodyBuilder, + headerBuilder: widget.headerBuilder, + headerHeight: widget.headerHeight, + currentExtent: _controller.isAttached + ? _controller.size + : widget.initHeightFraction, + scrollController: controller, + cacheExtent: _calculateCacheExtent( + MediaQuery.viewInsetsOf(context).bottom, + ), ), ), ), - ), - ); - }, + ); + }, + ), ), ), - ), - if (bottomPaddingHeight > 0) - SizedBox( - width: double.infinity, - height: bottomPaddingHeight, - child: ColoredBox(color: backgroundColor), - ), - ], + if (bottomPaddingHeight > 0) + SizedBox( + width: double.infinity, + height: bottomPaddingHeight, + child: ColoredBox(color: backgroundColor), + ), + ], + ), ), ); } diff --git a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet_route.dart b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet_route.dart index 3609f74faf5c..60953385472f 100644 --- a/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet_route.dart +++ b/packages/smooth_app/lib/generic_lib/bottom_sheets/smooth_draggable_bottom_sheet_route.dart @@ -8,7 +8,9 @@ Future showDraggableModalSheet({ required double headerHeight, required WidgetBuilder bodyBuilder, required BorderRadiusGeometry borderRadius, + DraggableScrollableController? draggableScrollableController, double? initHeight, + double? minHeight, double? maxHeight, Color? bottomSheetColor, Color? barrierColor, @@ -19,6 +21,7 @@ Future showDraggableModalSheet({ return Navigator.of(context, rootNavigator: true).push( _FlexibleBottomSheetRoute( + draggableScrollableController: draggableScrollableController, barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel, initHeight: initHeight ?? 0.5, bodyBuilder: bodyBuilder, @@ -38,6 +41,8 @@ class _FlexibleBottomSheetRoute extends PopupRoute { required this.headerHeight, required this.bodyBuilder, required this.borderRadius, + this.minHeight, + this.draggableScrollableController, this.barrierLabel, this.bottomSheetBackgroundColor, super.settings, @@ -46,9 +51,11 @@ class _FlexibleBottomSheetRoute extends PopupRoute { final WidgetBuilder headerBuilder; final double headerHeight; final WidgetBuilder bodyBuilder; + final double? minHeight; final double initHeight; final BorderRadiusGeometry borderRadius; final Color? bottomSheetBackgroundColor; + final DraggableScrollableController? draggableScrollableController; @override final String? barrierLabel; @@ -85,6 +92,7 @@ class _FlexibleBottomSheetRoute extends PopupRoute { context: context, child: SmoothDraggableBottomSheet( initHeightFraction: initHeight, + draggableScrollableController: draggableScrollableController, headerBuilder: headerBuilder, bodyBuilder: bodyBuilder, animationController: _animationController, diff --git a/packages/smooth_app/lib/helpers/product_compatibility_helper.dart b/packages/smooth_app/lib/helpers/product_compatibility_helper.dart index 1c5f76d18611..1f14e7b4b2f4 100644 --- a/packages/smooth_app/lib/helpers/product_compatibility_helper.dart +++ b/packages/smooth_app/lib/helpers/product_compatibility_helper.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:openfoodfacts/openfoodfacts.dart'; -import 'package:smooth_app/generic_lib/design_constants.dart'; +import 'package:smooth_app/themes/smooth_theme_colors.dart'; class ProductCompatibilityHelper { ProductCompatibilityHelper.product(final MatchedProductV2 product) @@ -11,20 +11,18 @@ class ProductCompatibilityHelper { final MatchedProductStatusV2 status; - Color getHeaderBackgroundColor(bool darkMode) { - if (darkMode) { - return _getDarkColors(); - } else { - return _getLightColors(); - } - } + Color getColor(BuildContext context) { + final SmoothColorsThemeExtension theme = + Theme.of(context).extension()!; - Color getButtonColor(bool darkMode) { - if (darkMode) { - return _getLightColors(); - } else { - return _getDarkColors(); - } + return switch (status) { + MatchedProductStatusV2.VERY_GOOD_MATCH => theme.green, + MatchedProductStatusV2.GOOD_MATCH => theme.green, + MatchedProductStatusV2.POOR_MATCH => theme.orange, + MatchedProductStatusV2.MAY_NOT_MATCH => theme.orange, + MatchedProductStatusV2.DOES_NOT_MATCH => theme.red, + MatchedProductStatusV2.UNKNOWN_MATCH => theme.greyNormal, + }; } Color getHeaderForegroundColor(bool darkMode) => @@ -33,30 +31,6 @@ class ProductCompatibilityHelper { Color getButtonForegroundColor(bool darkMode) => getHeaderForegroundColor(darkMode); - // According to color contrast tool https://material.io/resources/color - // on all those background colors the best is to write in black. - Color _getDarkColors() { - switch (status) { - case MatchedProductStatusV2.VERY_GOOD_MATCH: - return DARK_GREEN_COLOR; - case MatchedProductStatusV2.GOOD_MATCH: - return LIGHT_GREEN_COLOR; - case MatchedProductStatusV2.POOR_MATCH: - return DARK_YELLOW_COLOR; - case MatchedProductStatusV2.MAY_NOT_MATCH: - return DARK_ORANGE_COLOR; - case MatchedProductStatusV2.DOES_NOT_MATCH: - return RED_COLOR; - case MatchedProductStatusV2.UNKNOWN_MATCH: - return FAIR_GREY_COLOR; - } - } - - Color _getLightColors() { - // TODO(monsieurtanuki): difference between dark and light - return _getDarkColors(); - } - String getHeaderText(final AppLocalizations appLocalizations) { switch (status) { case MatchedProductStatusV2.VERY_GOOD_MATCH: diff --git a/packages/smooth_app/lib/l10n/app_en.arb b/packages/smooth_app/lib/l10n/app_en.arb index 7daf6dde94b0..c473f6d0ec03 100644 --- a/packages/smooth_app/lib/l10n/app_en.arb +++ b/packages/smooth_app/lib/l10n/app_en.arb @@ -1584,7 +1584,7 @@ "@user_list_button_new": { "description": "Short label of a 'create a new list' button" }, - "user_list_empty_label": "No list available yet, please start by creating one", + "user_list_empty_label": "No list available yet!\nPlease start by creating one.", "@user_list_empty_label": { "description": "Content displayed when there is no list" }, @@ -2533,9 +2533,9 @@ "@user_picture_source_remember": { "description": "Checkbox label when select a picture source" }, - "user_picture_source_select": "Select each time", - "@user_picture_source_select": { - "description": "Choice of selecting the picture source each time" + "user_picture_source_ask": "Ask each time", + "@user_picture_source_ask": { + "description": "Choice of asking the picture source every time" }, "robotoff_continue": "Continue", "@robotoff_continue": { @@ -3073,5 +3073,9 @@ "photo_viewer_details_url_title": "URL", "@photo_viewer_details_url_title": { "description": "Label for the link of a photo" + }, + "product_page_compatibility_score": "Compatible", + "@product_page_compatibility_score": { + "description": "Compatibility score on top of the product page. The sentence is \"100%\" Compatible" } } \ No newline at end of file diff --git a/packages/smooth_app/lib/pages/personalized_ranking_page.dart b/packages/smooth_app/lib/pages/personalized_ranking_page.dart index 8441d94c5167..cc4a9d31eae8 100644 --- a/packages/smooth_app/lib/pages/personalized_ranking_page.dart +++ b/packages/smooth_app/lib/pages/personalized_ranking_page.dart @@ -241,7 +241,7 @@ class _PersonalizedRankingPageState extends State barcode: matchedProduct.barcode, backgroundColor: ProductCompatibilityHelper.status(matchedProduct.status) - .getHeaderBackgroundColor(darkMode) + .getColor(context) .withAlpha(_backgroundAlpha), ), ); diff --git a/packages/smooth_app/lib/pages/preferences/user_preferences_account.dart b/packages/smooth_app/lib/pages/preferences/user_preferences_account.dart index 0548121d3449..4f93b6b6ff16 100644 --- a/packages/smooth_app/lib/pages/preferences/user_preferences_account.dart +++ b/packages/smooth_app/lib/pages/preferences/user_preferences_account.dart @@ -298,7 +298,7 @@ class UserPreferencesAccount extends AbstractUserPreferences { localDatabase: localDatabase, productQuery: productQuery, context: context, - editableAppBarTitle: false, + editableAppBarTitle: true, ), iconData, lazyCounter: lazyCounter, diff --git a/packages/smooth_app/lib/pages/preferences/user_preferences_image_source.dart b/packages/smooth_app/lib/pages/preferences/user_preferences_image_source.dart index a2177e25eb85..bdfaf5581274 100644 --- a/packages/smooth_app/lib/pages/preferences/user_preferences_image_source.dart +++ b/packages/smooth_app/lib/pages/preferences/user_preferences_image_source.dart @@ -15,7 +15,7 @@ class UserPreferencesImageSource extends StatelessWidget { return UserPreferencesItemSimple( labels: [ appLocalizations.choose_image_source_title, - appLocalizations.user_picture_source_select, + appLocalizations.user_picture_source_ask, appLocalizations.settings_app_camera, appLocalizations.gallery_source_label, ], @@ -35,7 +35,7 @@ class UserPreferencesImageSource extends StatelessWidget { (_) => const Icon(Icons.image), ], labels: [ - appLocalizations.user_picture_source_select, + appLocalizations.user_picture_source_ask, appLocalizations.settings_app_camera, appLocalizations.gallery_source_label, ], diff --git a/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart b/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart index a5cdbdf33cd0..37705b4fc439 100644 --- a/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart +++ b/packages/smooth_app/lib/pages/preferences/user_preferences_widgets.dart @@ -6,6 +6,7 @@ import 'package:smooth_app/generic_lib/design_constants.dart'; import 'package:smooth_app/generic_lib/dialogs/smooth_alert_dialog.dart'; import 'package:smooth_app/pages/preferences/user_preferences_item.dart'; import 'package:smooth_app/themes/smooth_theme_colors.dart'; +import 'package:smooth_app/themes/theme_provider.dart'; /// A dashed line class UserPreferencesListItemDivider extends StatelessWidget { @@ -443,7 +444,13 @@ class _ChoiceItem extends StatelessWidget { @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); - final Color? selectedColor = selected ? theme.primaryColor : null; + final SmoothColorsThemeExtension extension = + theme.extension()!; + final Color? selectedColor = selected + ? context.lightTheme() + ? extension.primaryMedium + : extension.primaryDark + : null; return Semantics( value: label, @@ -451,7 +458,7 @@ class _ChoiceItem extends StatelessWidget { button: true, excludeSemantics: true, child: Ink( - color: selectedColor?.withOpacity(0.1) ?? Colors.transparent, + color: selectedColor ?? Colors.transparent, child: Column( children: [ ListTile( diff --git a/packages/smooth_app/lib/pages/product/compare_products3_page.dart b/packages/smooth_app/lib/pages/product/compare_products3_page.dart index 56b967f430ae..c69c6f38d60a 100644 --- a/packages/smooth_app/lib/pages/product/compare_products3_page.dart +++ b/packages/smooth_app/lib/pages/product/compare_products3_page.dart @@ -69,8 +69,6 @@ class _CompareProducts3PageState extends State { final AppLocalizations appLocalizations = AppLocalizations.of(context); context.watch(); - final bool darkMode = Theme.of(context).brightness == Brightness.dark; - final ProductPreferences productPreferences = context.watch(); final List> scoreAttributesArray = >[]; @@ -85,7 +83,7 @@ class _CompareProducts3PageState extends State { scoreWidgets.add( Expanded( child: Container( - color: helper.getHeaderBackgroundColor(darkMode), + color: helper.getColor(context), child: Center( child: Text( matchedProduct.score.toInt().toString(), diff --git a/packages/smooth_app/lib/pages/product/product_compatibility_header.dart b/packages/smooth_app/lib/pages/product/product_compatibility_header.dart index ebd720c34d5e..e01324bc84ac 100644 --- a/packages/smooth_app/lib/pages/product/product_compatibility_header.dart +++ b/packages/smooth_app/lib/pages/product/product_compatibility_header.dart @@ -25,6 +25,7 @@ class ProductCompatibilityHeader extends StatelessWidget { product, productPreferences, ); + final ProductCompatibilityHelper helper = ProductCompatibilityHelper.product(matchedProduct); final AppLocalizations appLocalizations = AppLocalizations.of(context); @@ -33,7 +34,7 @@ class ProductCompatibilityHeader extends StatelessWidget { return Ink( decoration: BoxDecoration( - color: helper.getHeaderBackgroundColor(isDarkMode), + color: helper.getColor(context), // Ensure that the header has the same circular radius as the SmoothCard. borderRadius: const BorderRadiusDirectional.only( topStart: ROUNDED_RADIUS, diff --git a/packages/smooth_app/lib/pages/product/product_list_helper.dart b/packages/smooth_app/lib/pages/product/product_list_helper.dart index 728ee6611e8a..0e73a66603d2 100644 --- a/packages/smooth_app/lib/pages/product/product_list_helper.dart +++ b/packages/smooth_app/lib/pages/product/product_list_helper.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:provider/provider.dart'; import 'package:smooth_app/data_models/product_list.dart'; @@ -8,12 +9,14 @@ import 'package:smooth_app/database/dao_product_list.dart'; import 'package:smooth_app/database/local_database.dart'; import 'package:smooth_app/generic_lib/buttons/smooth_simple_button.dart'; import 'package:smooth_app/generic_lib/design_constants.dart'; +import 'package:smooth_app/generic_lib/duration_constants.dart'; import 'package:smooth_app/helpers/collections_helper.dart'; import 'package:smooth_app/helpers/haptic_feedback_helper.dart'; import 'package:smooth_app/helpers/provider_helper.dart'; import 'package:smooth_app/pages/product_list_user_dialog_helper.dart'; import 'package:smooth_app/resources/app_icons.dart'; import 'package:smooth_app/themes/smooth_theme_colors.dart'; +import 'package:smooth_app/themes/theme_provider.dart'; import 'package:smooth_app/widgets/smooth_checkbox.dart'; class AddProductToListContainer extends StatelessWidget { @@ -137,35 +140,51 @@ class _AddToProductListNoListAvailable extends StatelessWidget { class _AddToProductListWithLists extends StatelessWidget { const _AddToProductListWithLists(); - static const double MIN_ITEM_HEIGHT = 48.0; + static const double MIN_ITEM_HEIGHT = 58.0; @override Widget build(BuildContext context) { final _ProductUserListsWithState state = context .watch<_ProductUserListsProvider>() .value as _ProductUserListsWithState; + final List> userLists = state.userLists; + final bool? scrollBarVisible = userLists.length > 5 ? true : null; - return SliverList( - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == 0) { - return _AddToProductListAddNewList( - userLists: state.userLists.map((MapEntry entry) { - return entry.key; - }), - ); - } else if (index <= state.userLists.length) { - final MapEntry entry = state.userLists[index - 1]; - return _AddToProductListItem( - listId: entry.key, - selected: entry.value, - includeDivider: index < state.userLists.length, - ); - } else { - return SizedBox(height: MediaQuery.viewPaddingOf(context).bottom); - } - }, - childCount: state.userLists.length + 2, + return DefaultTextStyle.merge( + style: TextStyle( + fontSize: 15.0, + color: Theme.of(context).colorScheme.onSurface, + ), + child: SliverFillRemaining( + child: Column(children: [ + Expanded( + child: Scrollbar( + thumbVisibility: scrollBarVisible, + trackVisibility: scrollBarVisible, + child: ListView.builder( + padding: EdgeInsets.zero, + itemCount: userLists.length, + itemBuilder: (BuildContext context, int index) { + final MapEntry entry = userLists[index]; + return KeyedSubtree( + key: ValueKey(entry.key), + child: _AddToProductListItem( + listId: entry.key, + selected: entry.value, + // Force the divider when there is just one item + includeDivider: + userLists.length == 1 || index < userLists.length - 1, + ), + ); + }, + ), + ), + ), + _AddToProductListAddNewList( + userLists: + userLists.map((MapEntry entry) => entry.key), + ) + ]), ), ); } @@ -244,97 +263,165 @@ class _AddToProductListAddNewList extends StatefulWidget { } class _AddToProductListAddNewListState - extends State<_AddToProductListAddNewList> { + extends State<_AddToProductListAddNewList> + with WidgetsBindingObserver, SingleTickerProviderStateMixin { final TextEditingController _controller = TextEditingController(); + late final AnimationController _animationController; + Animation? _colorAnimation; + int animationRepeat = 0; + bool _editMode = false; bool _inputValid = false; + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + duration: SmoothAnimationsDuration.short, + ); + + SchedulerBinding.instance.addPostFrameCallback((_) { + _initAnimation(); + }); + } + + void _initAnimation() { + final SmoothColorsThemeExtension extension = + Theme.of(context).extension()!; + final bool lightTheme = context.lightTheme(listen: false); + + _colorAnimation = ColorTween( + begin: lightTheme ? extension.primaryLight : extension.primarySemiDark, + end: extension.red, + ).animate(_animationController) + ..addListener(() { + setState(() {}); + }) + ..addStatusListener((AnimationStatus status) { + // Run back and forth the animation twice + if (status == AnimationStatus.completed && animationRepeat < 2) { + _animationController.reverse(); + } else if (status == AnimationStatus.dismissed && animationRepeat < 1) { + animationRepeat++; + _animationController.forward(); + } + }); + + setState(() {}); + } + @override Widget build(BuildContext context) { final AppLocalizations appLocalizations = AppLocalizations.of(context); - final Color? mainColor = Theme.of(context) - .checkboxTheme - .fillColor! - .resolve({WidgetState.selected}); - - return Column( - children: [ - IconTheme( - data: IconThemeData(color: mainColor), - child: InkWell( - onTap: () { - setState(() { - if (!_editMode) { - _controller.clear(); - _editMode = true; - _inputValid = false; - } - }); - }, - child: ConstrainedBox( - constraints: const BoxConstraints( - minHeight: _AddToProductListWithLists.MIN_ITEM_HEIGHT, + final SmoothColorsThemeExtension extension = + Theme.of(context).extension()!; + final bool lightTheme = context.lightTheme(); + + final Color iconColor = lightTheme + ? Theme.of(context) + .checkboxTheme + .fillColor! + .resolve({WidgetState.selected})! + : Colors.white; + + return IconTheme( + data: IconThemeData(color: iconColor), + child: Padding( + padding: const EdgeInsetsDirectional.symmetric(horizontal: SMALL_SPACE), + child: InkWell( + borderRadius: const BorderRadius.vertical(top: Radius.circular(10.0)), + onTap: () { + setState(() { + if (!_editMode) { + _controller.clear(); + _editMode = true; + _inputValid = false; + } + }); + }, + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + color: _colorAnimation?.value, + border: Border.all( + color: lightTheme + ? extension.primaryNormal + : extension.primaryLight, + ), + ), + child: Padding( + padding: EdgeInsetsDirectional.only( + bottom: MediaQuery.viewInsetsOf(context).bottom, ), - child: Padding( - padding: EdgeInsetsDirectional.symmetric( - horizontal: - (Platform.isIOS || Platform.isMacOS) ? 25.5 : 28.0, + child: ConstrainedBox( + constraints: const BoxConstraints( + minHeight: _AddToProductListWithLists.MIN_ITEM_HEIGHT, ), - child: Row( - children: [ - const Icon(Icons.add_circle_rounded), - const SizedBox(width: VERY_LARGE_SPACE), - Expanded( - child: _editMode - ? Padding( - padding: - const EdgeInsetsDirectional.only(bottom: 1.0), - child: TextField( - controller: _controller, - autofocus: true, - decoration: InputDecoration( - isDense: true, - hintText: appLocalizations - .user_list_name_input_hint, - hintStyle: TextStyle( - fontStyle: FontStyle.italic, - color: Theme.of(context).hintColor, + child: Padding( + padding: EdgeInsetsDirectional.only( + start: (Platform.isIOS || Platform.isMacOS) ? 18.5 : 21.0, + end: 5.0, + ), + child: Row( + children: [ + const Icon(Icons.add_circle_rounded), + const SizedBox(width: VERY_LARGE_SPACE), + Expanded( + child: _editMode + ? Padding( + padding: const EdgeInsetsDirectional.only( + bottom: 1.0), + child: TextField( + controller: _controller, + autofocus: true, + decoration: InputDecoration( + isDense: true, + hintText: appLocalizations + .user_list_name_input_hint, + hintStyle: TextStyle( + fontStyle: FontStyle.italic, + color: Theme.of(context).hintColor, + ), + contentPadding: EdgeInsets.zero, + border: InputBorder.none, ), - contentPadding: EdgeInsets.zero, - border: InputBorder.none, + textInputAction: TextInputAction.done, + maxLines: 1, + textAlignVertical: TextAlignVertical.top, + style: DefaultTextStyle.of(context).style, + onChanged: _checkInput, + onSubmitted: (_) => _addList(context), ), - textInputAction: TextInputAction.done, - maxLines: 1, - textAlignVertical: TextAlignVertical.top, - style: DefaultTextStyle.of(context).style, - onChanged: _checkInput, - onSubmitted: (_) => _inputValid - ? () => _addList(context) - : null, + ) + : Text( + appLocalizations.user_list_button_new, ), - ) - : Text( - appLocalizations.user_list_button_new, - ), - ), - if (_editMode) - IconButton( - icon: const Icon(Icons.cancel), - onPressed: () => setState(() => _editMode = false), - ), - if (_editMode) - IconButton( - icon: const Icon(Icons.check_circle), - onPressed: _inputValid ? () => _addList(context) : null, ), - ], + if (_editMode) + IconButton( + icon: const Icon(Icons.cancel), + onPressed: () => setState(() => _editMode = false), + tooltip: MaterialLocalizations.of(context) + .cancelButtonLabel, + ), + if (_editMode) + IconButton( + icon: const Icon(Icons.check_circle), + color: _inputValid + ? iconColor + : iconColor.withOpacity(0.4), + tooltip: appLocalizations.product_list_create_tooltip, + onPressed: () => _addList(context), + ), + ], + ), ), ), ), ), ), - const _AddToProductListDivider(), - ], + ), ); } @@ -351,6 +438,7 @@ class _AddToProductListAddNewListState void _addList(BuildContext context) { if (!_inputValid) { + _notifyWrongInput(); return; } @@ -360,30 +448,84 @@ class _AddToProductListAddNewListState setState(() => _editMode = false); } + + void _notifyWrongInput() { + animationRepeat = 0; + _animationController.forward(from: 0.0); + SmoothHapticFeedback.error(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } } +/// A dashed divider class _AddToProductListDivider extends StatelessWidget { const _AddToProductListDivider(); @override Widget build(BuildContext context) { + final SmoothColorsThemeExtension extension = + Theme.of(context).extension()!; return Padding( padding: const EdgeInsetsDirectional.symmetric( horizontal: LARGE_SPACE, ), - child: SizedBox( - height: 1.0, - width: double.infinity, - child: ColoredBox( - color: Theme.of(context) - .extension()! - .primaryLight, + child: CustomPaint( + size: const Size(double.infinity, 1.0), + painter: _AddToProductListDividerPainter( + dashWidth: 8.0, + dashSpace: 5.0, + color: context.lightTheme() + ? extension.primaryNormal + : extension.primaryLight, ), ), ); } } +class _AddToProductListDividerPainter extends CustomPainter { + _AddToProductListDividerPainter({ + required Color color, + required this.dashWidth, + required this.dashSpace, + }) : assert(color != Colors.transparent), + assert(dashWidth >= 0), + assert(dashSpace >= 0), + _paint = Paint() + ..color = color + ..strokeWidth = 1.0 + ..style = PaintingStyle.stroke; + + final Paint _paint; + final double dashWidth; + final double dashSpace; + + @override + void paint(Canvas canvas, Size size) { + double startX = 0.0; + while (startX < size.width) { + canvas.drawLine( + Offset(startX, 0), + Offset(startX + dashWidth, 0), + _paint, + ); + startX += dashWidth + dashSpace; + } + } + + @override + bool shouldRepaint(_AddToProductListDividerPainter oldDelegate) => false; + + @override + bool shouldRebuildSemantics(_AddToProductListDividerPainter oldDelegate) => + false; +} + /// Logic for the user lists class _ProductUserListsProvider extends ValueNotifier<_ProductUserListsState> { _ProductUserListsProvider(this.dao, this.barcode) @@ -403,12 +545,12 @@ class _ProductUserListsProvider extends ValueNotifier<_ProductUserListsState> { return; } - // Sort by ignoring case +// Sort by ignoring case lists.sort( (String a, String b) => a.toLowerCase().compareTo(b.toLowerCase()), ); - // Create a list of user lists with a boolean if the product is in it +// Create a list of user lists with a boolean if the product is in it final List listsWithProduct = await dao.getUserListsWithBarcodes([barcode]); diff --git a/packages/smooth_app/lib/pages/product/product_page/new_product_footer.dart b/packages/smooth_app/lib/pages/product/product_page/new_product_footer.dart index 19f91e8ab183..0dc3e526ea1c 100644 --- a/packages/smooth_app/lib/pages/product/product_page/new_product_footer.dart +++ b/packages/smooth_app/lib/pages/product/product_page/new_product_footer.dart @@ -118,19 +118,13 @@ class _ProductAddToListButton extends StatelessWidget { Future _editList(BuildContext context, Product product) async { final AppLocalizations appLocalizations = AppLocalizations.of(context); - final SmoothColorsThemeExtension? extension = - Theme.of(context).extension(); showSmoothDraggableModalSheet( context: context, header: SmoothModalSheetHeader( - backgroundColor: extension!.primaryDark, - foregroundColor: Colors.white, prefix: const SmoothModalSheetHeaderPrefixIndicator(), title: appLocalizations.user_list_title, - suffix: const SmoothModalSheetHeaderCloseButton( - addPadding: true, - ), + suffix: const SmoothModalSheetHeaderCloseButton(), ), bodyBuilder: (BuildContext context) => AddProductToListContainer( barcode: product.barcode!, @@ -160,19 +154,7 @@ class _ProductAddPriceButton extends StatelessWidget { return _ProductFooterFilledButton( label: appLocalizations.prices_add_a_price, - icon: switch (currency) { - Currency.GBP => const icons.AddPrice.britishPound(), - Currency.USD => const icons.AddPrice.dollar(), - Currency.EUR => const icons.AddPrice.euro(), - Currency.RUB => const icons.AddPrice.ruble(), - Currency.INR => const icons.AddPrice.rupee(), - Currency.CHF => const icons.AddPrice.swissFranc(), - Currency.TRY => const icons.AddPrice.turkishLira(), - Currency.UAH => const icons.AddPrice.ukrainianHryvnia(), - Currency.KRW => const icons.AddPrice.won(), - Currency.JPY => const icons.AddPrice.yen(), - _ => const icons.AddPrice.dollar(), - }, + icon: icons.AddPrice(currency), onTap: () => _addAPrice(context, context.read()), ); }, @@ -383,6 +365,8 @@ class _ProductFooterFilledButton extends StatelessWidget { Widget build(BuildContext context) { final SmoothColorsThemeExtension themeExtension = Theme.of(context).extension()!; + final ProductPageCompatibility compatibility = + context.watch(); return Semantics( excludeSemantics: true, @@ -392,9 +376,11 @@ class _ProductFooterFilledButton extends StatelessWidget { onPressed: onTap, style: OutlinedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: context.lightTheme() - ? themeExtension.primaryBlack - : themeExtension.primarySemiDark, + backgroundColor: compatibility.score > 0 + ? compatibility.color + : context.lightTheme() + ? themeExtension.primaryBlack + : themeExtension.primarySemiDark, side: BorderSide.none, ), child: Row( diff --git a/packages/smooth_app/lib/pages/product/product_page/new_product_header.dart b/packages/smooth_app/lib/pages/product/product_page/new_product_header.dart new file mode 100644 index 000000000000..00e784fef71d --- /dev/null +++ b/packages/smooth_app/lib/pages/product/product_page/new_product_header.dart @@ -0,0 +1,298 @@ +import 'dart:math' as math; + +import 'package:flutter/material.dart' hide Listener; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:openfoodfacts/openfoodfacts.dart'; +import 'package:provider/provider.dart'; +import 'package:smooth_app/generic_lib/design_constants.dart'; +import 'package:smooth_app/helpers/num_utils.dart'; +import 'package:smooth_app/helpers/provider_helper.dart'; +import 'package:smooth_app/pages/navigator/app_navigator.dart'; +import 'package:smooth_app/pages/preferences/user_preferences_page.dart'; +import 'package:smooth_app/pages/product/product_page/new_product_page.dart'; +import 'package:smooth_app/resources/app_icons.dart' as icons; +import 'package:smooth_app/themes/constant_icons.dart'; +import 'package:visibility_detector/visibility_detector.dart'; + +class ProductHeader extends StatefulWidget { + const ProductHeader({ + super.key, + }); + + @override + State createState() => _ProductHeaderState(); +} + +class _ProductHeaderState extends State { + double _titleOpacity = 0.0; + double _compatibilityScoreOpacity = 0.0; + + @override + Widget build(BuildContext context) { + final double statusBarHeight = MediaQuery.viewPaddingOf(context).top; + + return VisibilityDetector( + key: const Key('product_header'), + onVisibilityChanged: _onVisibilityChanged, + child: Listener( + listener: ( + _, + __, + ScrollController scrollController, + ) => + _onScroll(scrollController), + child: Consumer( + builder: (BuildContext context, + ProductPageCompatibility productCompatibility, _) { + return Material( + color: productCompatibility.color, + child: DefaultTextStyle.merge( + style: const TextStyle(color: Colors.white), + child: IconTheme( + data: const IconThemeData(color: Colors.white), + child: SizedBox( + height: kToolbarHeight + statusBarHeight, + child: Padding( + padding: EdgeInsetsDirectional.only(top: statusBarHeight), + child: Row( + children: [ + const _ProductHeaderBackButton(), + Expanded( + child: Offstage( + offstage: _titleOpacity == 0.0, + child: Opacity( + opacity: _titleOpacity, + child: const _ProductHeaderName(), + ), + ), + ), + if (productCompatibility.score > 0) + _ProductCompatibilityScore( + progress: _compatibilityScoreOpacity, + ), + ], + ), + ), + ), + ), + ), + ); + }, + ), + ), + ); + } + + void _onScroll(ScrollController scrollController) { + /// Get the title opacity depending on the scroll position + final double titleOpacity = + scrollController.offset.progressAndClamp(20.0, kToolbarHeight, 1.0); + final double compatibilityScoreOpacity = + scrollController.offset.progressAndClamp(20.0, kToolbarHeight * 2, 1.0); + + if (_titleOpacity != titleOpacity || + _compatibilityScoreOpacity != compatibilityScoreOpacity) { + _titleOpacity = titleOpacity; + _compatibilityScoreOpacity = compatibilityScoreOpacity; + + // Calling setState() may already be in a build() call + SchedulerBinding.instance.addPostFrameCallback((_) { + setState(() {}); + }); + } + } + + /// Change the status bar to a transparent one + void _onVisibilityChanged(VisibilityInfo info) { + if (info.visibleFraction == 1.0) { + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: Brightness.dark, + statusBarIconBrightness: Brightness.light, + ), + ); + } + } +} + +class _ProductHeaderBackButton extends StatelessWidget { + const _ProductHeaderBackButton(); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 56.0, + child: Tooltip( + message: MaterialLocalizations.of(context).backButtonTooltip, + child: InkWell( + customBorder: const CircleBorder(), + onTap: () { + Navigator.of(context).maybePop(); + }, + child: SizedBox.expand( + child: Icon(ConstantIcons.instance.getBackIcon()), + ), + ), + ), + ); + } +} + +class _ProductHeaderName extends StatelessWidget { + const _ProductHeaderName(); + + @override + Widget build(BuildContext context) { + return ConsumerFilter( + buildWhen: (Product? previousValue, Product currentValue) { + return previousValue?.brands != currentValue.brands || + previousValue?.productName != currentValue.productName; + }, + builder: (BuildContext context, Product product, _) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + product.productName ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 18.0, + height: 0.9, + ), + ), + Text( + product.brands ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16.5, + ), + ), + ], + ); + }, + ); + } +} + +class _ProductCompatibilityScore extends StatelessWidget { + const _ProductCompatibilityScore({ + required this.progress, + }); + + //ignore: constant_identifier_names + static const double MAX_WIDTH = 40.0; + static const EdgeInsetsGeometry PADDING = EdgeInsetsDirectional.only( + start: MEDIUM_SPACE, + end: BALANCED_SPACE, + ); + + final double progress; + + @override + Widget build(BuildContext context) { + final ProductPageCompatibility compatibility = + context.watch(); + + return Padding( + padding: PADDING, + child: SizedBox( + width: computeWidth(context) + (MAX_WIDTH * progress), + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: ROUNDED_BORDER_RADIUS, + border: Border.all(color: Colors.white), + ), + child: InkWell( + onTap: () => AppNavigator.of(context).push( + AppRoutes.PREFERENCES(PreferencePageType.FOOD), + ), + borderRadius: ROUNDED_BORDER_RADIUS, + child: ClipRRect( + borderRadius: ROUNDED_BORDER_RADIUS, + child: _getScoreWidget(context, compatibility), + ), + ), + ), + ), + ); + } + + Widget _getScoreWidget( + BuildContext context, + ProductPageCompatibility compatibility, + ) { + return IntrinsicHeight( + child: Row( + children: [ + Opacity( + opacity: progress, + child: Container( + width: MAX_WIDTH * progress, + height: double.infinity, + alignment: Alignment.center, + padding: const EdgeInsetsDirectional.only(start: 2.5), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadiusDirectional.horizontal( + start: Radius.circular(18.0), + ), + ), + child: Transform.translate( + offset: Offset((1 - progress) * 10, 0.0), + child: SizedBox( + child: icons.Info( + color: compatibility.color, + ), + ), + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + top: 6.0, + bottom: 8.0, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${compatibility.score.toInt()}%', + style: const TextStyle( + fontSize: 12.0, + height: 0.9, + fontWeight: FontWeight.bold, + ), + ), + Text( + AppLocalizations.of(context) + .product_page_compatibility_score, + style: const TextStyle( + fontSize: 9.0, + height: 0.9, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + double computeWidth(BuildContext context) { + return math.min( + 80.0, + (MediaQuery.sizeOf(context).width - PADDING.horizontal) * (18 / 100), + ); + } +} diff --git a/packages/smooth_app/lib/pages/product/product_page/new_product_page.dart b/packages/smooth_app/lib/pages/product/product_page/new_product_page.dart index 893a684006bc..0b8b82cd64c2 100644 --- a/packages/smooth_app/lib/pages/product/product_page/new_product_page.dart +++ b/packages/smooth_app/lib/pages/product/product_page/new_product_page.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:matomo_tracker/matomo_tracker.dart'; import 'package:openfoodfacts/openfoodfacts.dart'; import 'package:provider/provider.dart'; -import 'package:smooth_app/cards/product_cards/product_image_carousel.dart'; +import 'package:provider/single_child_widget.dart'; import 'package:smooth_app/data_models/preferences/user_preferences.dart'; import 'package:smooth_app/data_models/product_list.dart'; import 'package:smooth_app/data_models/product_preferences.dart'; @@ -14,12 +13,12 @@ import 'package:smooth_app/database/dao_product_list.dart'; import 'package:smooth_app/database/local_database.dart'; import 'package:smooth_app/generic_lib/buttons/smooth_large_button_with_icon.dart'; import 'package:smooth_app/generic_lib/design_constants.dart'; -import 'package:smooth_app/generic_lib/duration_constants.dart'; -import 'package:smooth_app/generic_lib/widgets/smooth_back_button.dart'; +import 'package:smooth_app/helpers/product_compatibility_helper.dart'; import 'package:smooth_app/pages/preferences/user_preferences_dev_mode.dart'; import 'package:smooth_app/pages/prices/prices_card.dart'; import 'package:smooth_app/pages/product/common/product_refresher.dart'; import 'package:smooth_app/pages/product/product_page/new_product_footer.dart'; +import 'package:smooth_app/pages/product/product_page/new_product_header.dart'; import 'package:smooth_app/pages/product/product_questions_widget.dart'; import 'package:smooth_app/pages/product/reorderable_knowledge_panel_page.dart'; import 'package:smooth_app/pages/product/reordered_knowledge_panel_cards.dart'; @@ -52,13 +51,11 @@ class ProductPage extends StatefulWidget { class ProductPageState extends State with TraceableClientMixin, UpToDateMixin { - final ScrollController _carouselController = ScrollController(); - + final ScrollController _scrollController = ScrollController(); late ProductPreferences _productPreferences; late ProductQuestionsLayout questionsLayout; bool _keepRobotoffQuestionsAlive = true; - bool scrollingUp = true; double bottomPadding = 0.0; @override @@ -81,7 +78,6 @@ class ProductPageState extends State final ExternalScanCarouselManagerState carouselManager = ExternalScanCarouselManager.read(context); carouselManager.currentBarcode = barcode; - final ThemeData themeData = Theme.of(context); final SmoothColorsThemeExtension themeExtension = Theme.of(context).extension()!; @@ -89,79 +85,63 @@ class ProductPageState extends State context.watch(); refreshUpToDate(); + final MatchedProductV2 matchedProductV2 = MatchedProductV2( + upToDateProduct, + _productPreferences, + ); + return MultiProvider( - providers: >[ + providers: [ Provider.value(value: upToDateProduct), Provider.value(value: this), + Provider.value( + value: ProductPageCompatibility( + color: ProductCompatibilityHelper.product( + matchedProductV2, + ).getColor(context), + score: matchedProductV2.score, + ), + ), + ChangeNotifierProvider.value( + value: _scrollController, + ), ], - child: Provider.value( - value: upToDateProduct, - child: SmoothScaffold( - contentBehindStatusBar: true, - spaceBehindStatusBar: false, - statusBarBackgroundColor: SmoothScaffold.semiTranslucentStatusBar, - backgroundColor: - !context.darkTheme() ? themeExtension.primaryLight : null, - body: Stack( - children: [ - NotificationListener( - onNotification: (UserScrollNotification notification) { - if (notification.direction == ScrollDirection.forward) { - if (!scrollingUp) { - setState(() => scrollingUp = true); - } - } else if (notification.direction == - ScrollDirection.reverse) { - if (scrollingUp) { - setState(() => scrollingUp = false); + child: SmoothScaffold( + contentBehindStatusBar: true, + spaceBehindStatusBar: false, + changeStatusBarBrightness: false, + statusBarBackgroundColor: Colors.transparent, + backgroundColor: + !context.darkTheme() ? themeExtension.primaryLight : null, + body: Stack( + children: [ + _buildProductBody(context), + const Positioned( + left: 0.0, + right: 0.0, + top: 0.0, + child: ProductHeader(), + ), + if (questionsLayout == ProductQuestionsLayout.banner) + Positioned( + left: 0.0, + right: 0.0, + bottom: 0.0, + child: MeasureSize( + onChange: (Size size) { + if (size.height != bottomPadding) { + setState(() => bottomPadding = size.height); } - } - return true; - }, - child: _buildProductBody(context), - ), - Padding( - padding: const EdgeInsetsDirectional.only(start: SMALL_SPACE), - child: SafeArea( - child: AnimatedContainer( - duration: SmoothAnimationsDuration.short, - width: kToolbarHeight, - height: kToolbarHeight, - decoration: BoxDecoration( - color: scrollingUp - ? themeData.primaryColor - : Colors.transparent, - shape: BoxShape.circle, - ), - child: Offstage( - offstage: !scrollingUp, - child: const SmoothBackButton(iconColor: Colors.white), - ), + }, + child: ProductQuestionsWidget( + upToDateProduct, + layout: ProductQuestionsLayout.banner, ), ), ), - if (questionsLayout == ProductQuestionsLayout.banner) - Positioned.directional( - start: 0.0, - end: 0.0, - bottom: 0.0, - textDirection: Directionality.of(context), - child: MeasureSize( - onChange: (Size size) { - if (size.height != bottomPadding) { - setState(() => bottomPadding = size.height); - } - }, - child: ProductQuestionsWidget( - upToDateProduct, - layout: ProductQuestionsLayout.banner, - ), - ), - ), - ], - ), - bottomNavigationBar: const ProductFooter(), + ], ), + bottomNavigationBar: const ProductFooter(), ), ); } @@ -181,85 +161,81 @@ class ProductPageState extends State final AppLocalizations appLocalizations = AppLocalizations.of(context); final UserPreferences userPreferences = context.watch(); - return RefreshIndicator( - onRefresh: () async => ProductRefresher().fetchAndRefresh( - barcode: barcode, - context: context, - ), - child: ListView( - // /!\ Smart Dart - // `physics: const AlwaysScrollableScrollPhysics()` - // means that we will always scroll, even if it's pointless. - // Why do we need to? For the RefreshIndicator, that wouldn't be - // triggered on a ListView smaller than the screen - // (as there will be no scroll). - physics: const AlwaysScrollableScrollPhysics(), - padding: const EdgeInsets.only( - bottom: SMALL_SPACE, + return SafeArea( + child: RefreshIndicator( + onRefresh: () async => ProductRefresher().fetchAndRefresh( + barcode: barcode, + context: context, ), - children: [ - Align( - heightFactor: 0.7, - alignment: AlignmentDirectional.topStart, - child: ProductImageCarousel( - upToDateProduct, - height: 200, - controller: _carouselController, - ), + child: ListView( + // /!\ Smart Dart + // `physics: const AlwaysScrollableScrollPhysics()` + // means that we will always scroll, even if it's pointless. + // Why do we need to? For the RefreshIndicator, that wouldn't be + // triggered on a ListView smaller than the screen + // (as there will be no scroll). + physics: const AlwaysScrollableScrollPhysics(), + controller: _scrollController, + padding: const EdgeInsets.only( + top: kToolbarHeight + SMALL_SPACE, + bottom: SMALL_SPACE, ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: SMALL_SPACE, - ), - child: HeroMode( - enabled: widget.withHeroAnimation && - widget.heroTag?.isNotEmpty == true, - child: Hero( - tag: widget.heroTag ?? '', - child: KeepQuestionWidgetAlive( - keepWidgetAlive: _keepRobotoffQuestionsAlive, - child: SummaryCard( - upToDateProduct, - _productPreferences, - isFullVersion: true, - showQuestionsBanner: true, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: SMALL_SPACE, + ), + child: HeroMode( + enabled: widget.withHeroAnimation && + widget.heroTag?.isNotEmpty == true, + child: Hero( + tag: widget.heroTag ?? '', + child: KeepQuestionWidgetAlive( + keepWidgetAlive: _keepRobotoffQuestionsAlive, + child: SummaryCard( + upToDateProduct, + _productPreferences, + isFullVersion: true, + showQuestionsBanner: true, + showCompatibilityHeader: false, + ), ), ), ), ), - ), - if (userPreferences.getFlag( - UserPreferencesDevMode.userPreferencesFlagUserOrderedKP) ?? - false) - ReorderedKnowledgePanelCards(upToDateProduct) - else - StandardKnowledgePanelCards(upToDateProduct), - // TODO(monsieurtanuki): include website in reordered knowledge panels - if (upToDateProduct.website != null && - upToDateProduct.website!.trim().isNotEmpty) - WebsiteCard(upToDateProduct.website!), - PricesCard(upToDateProduct), - if (userPreferences.getFlag( - UserPreferencesDevMode.userPreferencesFlagUserOrderedKP) ?? - false) - Padding( - padding: const EdgeInsets.all(SMALL_SPACE), - child: SmoothLargeButtonWithIcon( - text: appLocalizations.reorder_attribute_action, - icon: Icons.sort, - onPressed: () async => Navigator.push( - context, - MaterialPageRoute( - builder: (_) => - ReorderableKnowledgePanelPage(upToDateProduct), + if (userPreferences.getFlag( + UserPreferencesDevMode.userPreferencesFlagUserOrderedKP) ?? + false) + ReorderedKnowledgePanelCards(upToDateProduct) + else + StandardKnowledgePanelCards(upToDateProduct), + // TODO(monsieurtanuki): include website in reordered knowledge panels + if (upToDateProduct.website != null && + upToDateProduct.website!.trim().isNotEmpty) + WebsiteCard(upToDateProduct.website!), + PricesCard(upToDateProduct), + if (userPreferences.getFlag( + UserPreferencesDevMode.userPreferencesFlagUserOrderedKP) ?? + false) + Padding( + padding: const EdgeInsets.all(SMALL_SPACE), + child: SmoothLargeButtonWithIcon( + text: appLocalizations.reorder_attribute_action, + icon: Icons.sort, + onPressed: () async => Navigator.push( + context, + MaterialPageRoute( + builder: (_) => + ReorderableKnowledgePanelPage(upToDateProduct), + ), ), ), ), - ), - if (questionsLayout == ProductQuestionsLayout.banner) - // assuming it's tall enough in order to go above the banner - const SizedBox(height: 4 * VERY_LARGE_SPACE), - ], + if (questionsLayout == ProductQuestionsLayout.banner) + // assuming it's tall enough in order to go above the banner + const SizedBox(height: 4 * VERY_LARGE_SPACE), + ], + ), ), ); } @@ -279,3 +255,26 @@ class ProductPageState extends State return result!; } } + +class ProductPageCompatibility { + ProductPageCompatibility({ + required this.color, + required this.score, + }); + + final Color color; + final double score; + + @override + //ignore: avoid_equals_and_hash_code_on_mutable_classes (false positive) + bool operator ==(Object other) => + identical(this, other) || + other is ProductPageCompatibility && + runtimeType == other.runtimeType && + color == other.color && + score == other.score; + + @override + //ignore: avoid_equals_and_hash_code_on_mutable_classes (false positive) + int get hashCode => color.hashCode ^ score.hashCode; +} diff --git a/packages/smooth_app/lib/pages/product/summary_card.dart b/packages/smooth_app/lib/pages/product/summary_card.dart index 43fa4841c773..5cf9c944118f 100644 --- a/packages/smooth_app/lib/pages/product/summary_card.dart +++ b/packages/smooth_app/lib/pages/product/summary_card.dart @@ -42,6 +42,7 @@ class SummaryCard extends StatefulWidget { this._productPreferences, { this.isFullVersion = false, this.showQuestionsBanner = false, + this.showCompatibilityHeader = true, this.isRemovable = true, this.isSettingVisible = true, this.isProductEditable = true, @@ -74,6 +75,9 @@ class SummaryCard extends StatefulWidget { /// If true, all chips / groups are clickable final bool attributeGroupsClickable; + /// If true, the compatibility header will be shown + final bool showCompatibilityHeader; + final EdgeInsetsGeometry? padding; /// An optional shadow to apply to the card @@ -107,11 +111,13 @@ class _SummaryCardState extends State with UpToDateMixin { refreshUpToDate(); if (widget.isFullVersion) { return buildProductSmoothCard( - header: ProductCompatibilityHeader( - product: upToDateProduct, - productPreferences: widget._productPreferences, - isSettingVisible: widget.isSettingVisible, - ), + header: widget.showCompatibilityHeader + ? ProductCompatibilityHeader( + product: upToDateProduct, + productPreferences: widget._productPreferences, + isSettingVisible: widget.isSettingVisible, + ) + : null, body: Padding( padding: widget.padding ?? SMOOTH_CARD_PADDING, child: _buildSummaryCardContent(context), diff --git a/packages/smooth_app/lib/resources/app_icons.dart b/packages/smooth_app/lib/resources/app_icons.dart index 7a64b267db9b..df6ca06a455c 100644 --- a/packages/smooth_app/lib/resources/app_icons.dart +++ b/packages/smooth_app/lib/resources/app_icons.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:openfoodfacts/openfoodfacts.dart' as off; part 'app_icons_font.dart'; @@ -14,6 +15,22 @@ class Add extends AppIcon { } class AddPrice extends AppIcon { + factory AddPrice(off.Currency currency) { + return switch (currency) { + off.Currency.GBP => const AddPrice.britishPound(), + off.Currency.USD => const AddPrice.dollar(), + off.Currency.EUR => const AddPrice.euro(), + off.Currency.RUB => const AddPrice.ruble(), + off.Currency.INR => const AddPrice.rupee(), + off.Currency.CHF => const AddPrice.swissFranc(), + off.Currency.TRY => const AddPrice.turkishLira(), + off.Currency.UAH => const AddPrice.ukrainianHryvnia(), + off.Currency.KRW => const AddPrice.won(), + off.Currency.JPY => const AddPrice.yen(), + _ => const AddPrice.dollar(), + }; + } + const AddPrice.britishPound({ super.color, super.size, @@ -94,6 +111,15 @@ class AddToList extends AppIcon { }) : super._(_IconsFont.add_to_list); } +class AppStore extends AppIcon { + const AppStore({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.app_store); +} + class Arrow extends AppIcon { const Arrow.right({ super.color, @@ -175,6 +201,13 @@ class Camera extends AppIcon { super.shadow, super.key, }) : super._(_IconsFont.camera_outlined); + + const Camera.happy({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.camera_happy); } class Categories extends AppIcon { @@ -266,6 +299,24 @@ class ClearText extends AppIcon { } } +class Delete extends AppIcon { + const Delete.trash({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.delete_trash); +} + +class Document extends AppIcon { + const Document({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.document); +} + class DoubleChevron extends AppIcon { const DoubleChevron.left({ super.color, @@ -337,6 +388,15 @@ class Compare extends AppIcon { }) : super._(_IconsFont.compare); } +class Contribute extends AppIcon { + const Contribute({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.contribute); +} + class Countries extends AppIcon { const Countries({ super.color, @@ -344,6 +404,13 @@ class Countries extends AppIcon { super.shadow, super.key, }) : super._(_IconsFont.countries); + + const Countries.alt({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.country); } class Cupcake extends AppIcon { @@ -355,6 +422,42 @@ class Cupcake extends AppIcon { }) : super._(_IconsFont.cupcake); } +class Crash extends AppIcon { + const Crash({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.crash); +} + +class Currency extends AppIcon { + const Currency({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.currency); +} + +class DangerousZone extends AppIcon { + const DangerousZone({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.dangerous_zone); +} + +class Donate extends AppIcon { + const Donate({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.donate); +} + class Edit extends AppIcon { const Edit({ super.color, @@ -391,6 +494,22 @@ class Expand extends AppIcon { }) : super._(_IconsFont.expand); } +class Eye extends AppIcon { + const Eye.visible({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.eye_visible); + + const Eye.invisible({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.eye_invisible); +} + class Fish extends AppIcon { const Fish({ super.color, @@ -409,6 +528,15 @@ class Fruit extends AppIcon { }) : super._(_IconsFont.fruit); } +class GitHub extends AppIcon { + const GitHub({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.github); +} + class Info extends AppIcon { const Info({ super.color, @@ -418,6 +546,15 @@ class Info extends AppIcon { }) : super._(_IconsFont.info); } +class HappyToast extends AppIcon { + const HappyToast({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.happy_toast); +} + class History extends AppIcon { const History({ super.color, @@ -436,6 +573,15 @@ class Help extends AppIcon { }) : super._(_IconsFont.help_circled); } +class Incognito extends AppIcon { + const Incognito({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.incognito); +} + class Ingredients extends AppIcon { const Ingredients({ super.color, @@ -443,6 +589,13 @@ class Ingredients extends AppIcon { super.shadow, super.key, }) : super._(_IconsFont.ingredients); + + const Ingredients.basket({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.ingredients_basket); } class Lab extends AppIcon { @@ -463,6 +616,22 @@ class Labels extends AppIcon { }) : super._(_IconsFont.labels); } +class Language extends AppIcon { + const Language({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.language); + + const Language.world({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.language_world); +} + class Lifebuoy extends AppIcon { const Lifebuoy({ super.color, @@ -472,6 +641,24 @@ class Lifebuoy extends AppIcon { }) : super._(_IconsFont.lifebuoy); } +class LightBulb extends AppIcon { + const LightBulb({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.light_bulb); +} + +class Logout extends AppIcon { + const Logout({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.logout); +} + class MagicWand extends AppIcon { const MagicWand({ super.color, @@ -481,6 +668,15 @@ class MagicWand extends AppIcon { }) : super._(_IconsFont.magic_wand); } +class Menu extends AppIcon { + const Menu.hamburger({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.hamburger_menu); +} + class Milk extends AppIcon { const Milk({ super.color, @@ -506,6 +702,13 @@ class NutritionFacts extends AppIcon { super.shadow, super.key, }) : super._(_IconsFont.nutrition_facts); + + const NutritionFacts.alt({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.nutritional_facts); } class Outdated extends AppIcon { @@ -526,6 +729,15 @@ class Packaging extends AppIcon { }) : super._(_IconsFont.packaging); } +class Password extends AppIcon { + const Password.lock({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.password); +} + class Personalization extends AppIcon { const Personalization({ super.color, @@ -533,6 +745,38 @@ class Personalization extends AppIcon { super.shadow, super.key, }) : super._(_IconsFont.personalization); + + const Personalization.alt({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.personalization_alt); +} + +class Picture extends AppIcon { + const Picture.add({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.image_add); + + const Picture.check({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.image_check); +} + +class Programming extends AppIcon { + const Programming({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.programming); } class Question extends AppIcon { @@ -752,6 +996,15 @@ class Torch extends AppIcon { }) : super._(_IconsFont.torch_off); } +class Vibration extends AppIcon { + const Vibration({ + super.color, + super.size, + super.shadow, + super.key, + }) : super._(_IconsFont.vibration); +} + class Warning extends AppIcon { const Warning({ super.color, diff --git a/packages/smooth_app/lib/resources/app_icons_font.dart b/packages/smooth_app/lib/resources/app_icons_font.dart index 9fc9a9471037..8d9132badf47 100644 --- a/packages/smooth_app/lib/resources/app_icons_font.dart +++ b/packages/smooth_app/lib/resources/app_icons_font.dart @@ -11,6 +11,8 @@ class _IconsFont { static const IconData chicken = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData eye_invisible = + IconData(0xe801, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData settings = IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData magic_wand = @@ -83,12 +85,20 @@ class _IconsFont { IconData(0xe824, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData torch_off = IconData(0xe825, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData language = + IconData(0xe826, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData sound_off = IconData(0xe827, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData sound_on = IconData(0xe828, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData torch_on = IconData(0xe829, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData camera_happy = + IconData(0xe82a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData vibration = + IconData(0xe82b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData programming = + IconData(0xe82c, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData add = IconData(0xe82d, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData barcode_corners = @@ -139,16 +149,62 @@ class _IconsFont { IconData(0xe846, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData add_to_list = IconData(0xe847, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData eye_visible = + IconData(0xe848, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData delete_trash = + IconData(0xe84a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData image_check = + IconData(0xe84b, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData image_add = + IconData(0xe84c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData app_store = + IconData(0xe84d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData document = + IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData github = + IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData ingredients_basket = + IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData close = IconData(0xe851, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData suggestion = IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData clear_text = IconData(0xe853, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData contribute = + IconData(0xe854, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData crash = + IconData(0xe855, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData currency = + IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData nutritional_facts = + IconData(0xe857, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData help_circled = IconData(0xe858, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData dots_vertical = IconData(0xe859, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData country = + IconData(0xe85a, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData hamburger_menu = + IconData(0xe85c, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData password = + IconData(0xe85d, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData incognito = + IconData(0xe85e, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData logout = + IconData(0xe85f, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData donate = + IconData(0xe861, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData dangerous_zone = + IconData(0xe862, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData happy_toast = + IconData(0xe863, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData light_bulb = + IconData(0xe864, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData language_world = + IconData(0xe865, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData personalization_alt = + IconData(0xe866, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData share_cupertino = IconData(0xe8a4, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData share_material = diff --git a/packages/smooth_app/lib/themes/smooth_theme_colors.dart b/packages/smooth_app/lib/themes/smooth_theme_colors.dart index 76637bd70e0a..d65d73ec0d79 100644 --- a/packages/smooth_app/lib/themes/smooth_theme_colors.dart +++ b/packages/smooth_app/lib/themes/smooth_theme_colors.dart @@ -16,6 +16,7 @@ class SmoothColorsThemeExtension required this.orange, required this.red, required this.greyDark, + required this.greyNormal, required this.greyLight, }); @@ -33,20 +34,27 @@ class SmoothColorsThemeExtension orange = const Color(0xFFFB8229), red = const Color(0xFFEB5757), greyDark = const Color(0xFF666666), + greyNormal = const Color(0xFF6C6C6C), greyLight = const Color(0xFF8F8F8F); // Ristreto final Color primaryUltraBlack; + // Chocolate final Color primaryBlack; + // Cortado final Color primaryDark; + // Mocha final Color primarySemiDark; + // Macchiato final Color primaryNormal; + // Cappuccino final Color primaryMedium; + // Latte final Color primaryLight; final Color secondaryNormal; @@ -55,6 +63,7 @@ class SmoothColorsThemeExtension final Color orange; final Color red; final Color greyDark; + final Color greyNormal; final Color greyLight; @override @@ -72,6 +81,7 @@ class SmoothColorsThemeExtension Color? orange, Color? red, Color? greyDark, + Color? greyNormal, Color? greyLight, }) { return SmoothColorsThemeExtension( @@ -88,6 +98,7 @@ class SmoothColorsThemeExtension orange: orange ?? this.orange, red: red ?? this.red, greyDark: greyDark ?? this.greyDark, + greyNormal: greyDark ?? this.greyDark, greyLight: greyLight ?? this.greyLight, ); } @@ -167,6 +178,11 @@ class SmoothColorsThemeExtension other.greyDark, t, )!, + greyNormal: Color.lerp( + greyNormal, + other.greyNormal, + t, + )!, greyLight: Color.lerp( greyLight, other.greyLight, diff --git a/packages/smooth_app/lib/widgets/smooth_scaffold.dart b/packages/smooth_app/lib/widgets/smooth_scaffold.dart index 08ef268854fc..2c75e2d2e08b 100644 --- a/packages/smooth_app/lib/widgets/smooth_scaffold.dart +++ b/packages/smooth_app/lib/widgets/smooth_scaffold.dart @@ -11,6 +11,7 @@ class SmoothScaffold extends Scaffold { this.contentBehindStatusBar = false, this.spaceBehindStatusBar = false, this.fixKeyboard = false, + this.changeStatusBarBrightness = true, bool? resizeToAvoidBottomInset, super.key, super.appBar, @@ -52,6 +53,7 @@ class SmoothScaffold extends Scaffold { final Color? statusBarBackgroundColor; final bool contentBehindStatusBar; final bool spaceBehindStatusBar; + final bool changeStatusBarBrightness; /// On some screens an extra padding maybe wrongly added when the keyboard is /// visible @@ -120,6 +122,10 @@ class SmoothScaffoldState extends ScaffoldState { } } + if (!_changeStatusBarBrightness) { + return child; + } + return AnnotatedRegion( value: _overlayStyle, child: Theme( @@ -139,6 +145,9 @@ class SmoothScaffoldState extends ScaffoldState { bool get _spaceBehindStatusBar => (widget as SmoothScaffold).spaceBehindStatusBar == true; + bool get _changeStatusBarBrightness => + (widget as SmoothScaffold).changeStatusBarBrightness == true; + Brightness? get _brightness => (widget as SmoothScaffold).brightness ?? SmoothBrightnessOverride.of(context)?.brightness; diff --git a/packages/smooth_app/macos/Podfile.lock b/packages/smooth_app/macos/Podfile.lock index 4321f61a951f..121461bdca51 100644 --- a/packages/smooth_app/macos/Podfile.lock +++ b/packages/smooth_app/macos/Podfile.lock @@ -117,13 +117,13 @@ SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 mobile_scanner: 54ceceae0c8da2457e26a362a6be5c61154b1829 - package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c + package_info_plus: f5790acc797bf17c3e959e9d6cf162cc68ff7523 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 ReachabilitySwift: 7f151ff156cea1481a8411701195ac6a984f4979 rive_common: cf5ab646aa576b2d742d0e2d528126fbf032c856 Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57 sentry_flutter: 0eb93e5279eb41e2392212afe1ccd2fecb4f8cbe - share_plus: 36537c04ce0c3e3f5bd297ce4318b6d5ee5fd6cf + share_plus: fd717ef89a2801d3491e737630112b80c310640e shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 sqflite_darwin: a553b1fd6fe66f53bbb0fe5b4f5bab93f08d7a13 url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 @@ -131,4 +131,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 0d3963a09fc94f580682bd88480486da345dc3f0 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/packages/smooth_app/pubspec.lock b/packages/smooth_app/pubspec.lock index 2835d86b890b..631b8f973fe8 100644 --- a/packages/smooth_app/pubspec.lock +++ b/packages/smooth_app/pubspec.lock @@ -696,10 +696,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "1b7723a814d84fb65869ea7115cdb3ee7c3be5a27a755c1ec60e049f6b9fcbb2" + sha256: de82e6bf958cec7190fbc1c5298282c851228e35ae2b14e2b103e7f777818c64 url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "2.0.13" flutter_test: dependency: "direct dev" description: flutter @@ -1101,10 +1101,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998 + sha256: da8d9ac8c4b1df253d1a328b7bf01ae77ef132833479ab40763334db13b91cce url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.1.1" package_info_plus_platform_interface: dependency: transitive description: @@ -1370,10 +1370,10 @@ packages: dependency: "direct main" description: name: share_plus - sha256: "3af2cda1752e5c24f2fc04b6083b40f013ffe84fb90472f30c6499a9213d5442" + sha256: "9c9bafd4060728d7cdb2464c341743adbd79d327cb067ec7afb64583540b47c8" url: "https://pub.dev" source: hosted - version: "10.1.1" + version: "10.1.2" share_plus_platform_interface: dependency: transitive description: diff --git a/packages/smooth_app/pubspec.yaml b/packages/smooth_app/pubspec.yaml index 239e82330241..2971d80fb064 100644 --- a/packages/smooth_app/pubspec.yaml +++ b/packages/smooth_app/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: barcode_widget: 2.0.4 carousel_slider: 5.0.0 cupertino_icons: 1.0.8 - flutter_svg: 2.0.13 + flutter_svg: 2.0.14 flutter_map: 7.0.2 html: 0.15.4 flutter_widget_from_html_core: 0.8.3+1 @@ -31,7 +31,7 @@ dependencies: iso_countries: 2.2.0 latlong2: 0.9.1 matomo_tracker: 5.1.0 - package_info_plus: 8.1.0 + package_info_plus: 8.1.1 device_info_plus: 10.1.2 permission_handler: 11.3.1 photo_view: 0.15.0 @@ -57,7 +57,7 @@ dependencies: collection: 1.18.0 path: 1.9.0 path_provider: 2.1.5 - share_plus: 10.1.1 + share_plus: 10.1.2 fimber: 0.7.0 shimmer: ^3.0.0 rive: 0.13.15