diff --git a/fonts-google.css b/fonts-google.css index 823d09a..e69de29 100644 --- a/fonts-google.css +++ b/fonts-google.css @@ -1,181 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: swap; - src: url(https://fonts.gstatic.com/s/robotoflex/v9/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} - diff --git a/public/public/Nacelle/Nacelle-Black.otf b/public/public/Nacelle/Nacelle-Black.otf new file mode 100644 index 0000000..bd95010 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Black.otf differ diff --git a/public/public/Nacelle/Nacelle-BlackItalic.otf b/public/public/Nacelle/Nacelle-BlackItalic.otf new file mode 100644 index 0000000..d067231 Binary files /dev/null and b/public/public/Nacelle/Nacelle-BlackItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-Bold.otf b/public/public/Nacelle/Nacelle-Bold.otf new file mode 100644 index 0000000..90b1b72 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Bold.otf differ diff --git a/public/public/Nacelle/Nacelle-BoldItalic.otf b/public/public/Nacelle/Nacelle-BoldItalic.otf new file mode 100644 index 0000000..037b7ab Binary files /dev/null and b/public/public/Nacelle/Nacelle-BoldItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-Heavy.otf b/public/public/Nacelle/Nacelle-Heavy.otf new file mode 100644 index 0000000..255d662 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Heavy.otf differ diff --git a/public/public/Nacelle/Nacelle-HeavyItalic.otf b/public/public/Nacelle/Nacelle-HeavyItalic.otf new file mode 100644 index 0000000..4ffcfd2 Binary files /dev/null and b/public/public/Nacelle/Nacelle-HeavyItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-Italic.otf b/public/public/Nacelle/Nacelle-Italic.otf new file mode 100644 index 0000000..49c0799 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Italic.otf differ diff --git a/public/public/Nacelle/Nacelle-Light.otf b/public/public/Nacelle/Nacelle-Light.otf new file mode 100644 index 0000000..a79c9b3 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Light.otf differ diff --git a/public/public/Nacelle/Nacelle-LightItalic.otf b/public/public/Nacelle/Nacelle-LightItalic.otf new file mode 100644 index 0000000..82d930d Binary files /dev/null and b/public/public/Nacelle/Nacelle-LightItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-Regular.otf b/public/public/Nacelle/Nacelle-Regular.otf new file mode 100644 index 0000000..7a0a454 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Regular.otf differ diff --git a/public/public/Nacelle/Nacelle-SemiBold.otf b/public/public/Nacelle/Nacelle-SemiBold.otf new file mode 100644 index 0000000..ae73865 Binary files /dev/null and b/public/public/Nacelle/Nacelle-SemiBold.otf differ diff --git a/public/public/Nacelle/Nacelle-SemiBoldItalic.otf b/public/public/Nacelle/Nacelle-SemiBoldItalic.otf new file mode 100644 index 0000000..8da9b27 Binary files /dev/null and b/public/public/Nacelle/Nacelle-SemiBoldItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-Thin.otf b/public/public/Nacelle/Nacelle-Thin.otf new file mode 100644 index 0000000..525f1f7 Binary files /dev/null and b/public/public/Nacelle/Nacelle-Thin.otf differ diff --git a/public/public/Nacelle/Nacelle-ThinItalic.otf b/public/public/Nacelle/Nacelle-ThinItalic.otf new file mode 100644 index 0000000..9082b35 Binary files /dev/null and b/public/public/Nacelle/Nacelle-ThinItalic.otf differ diff --git a/public/public/Nacelle/Nacelle-UltraLight.otf b/public/public/Nacelle/Nacelle-UltraLight.otf new file mode 100644 index 0000000..26c8158 Binary files /dev/null and b/public/public/Nacelle/Nacelle-UltraLight.otf differ diff --git a/public/public/Nacelle/Nacelle-UltraLightItalic.otf b/public/public/Nacelle/Nacelle-UltraLightItalic.otf new file mode 100644 index 0000000..523f255 Binary files /dev/null and b/public/public/Nacelle/Nacelle-UltraLightItalic.otf differ diff --git a/public/public/Nacelle/SIL Open Font License.txt b/public/public/Nacelle/SIL Open Font License.txt new file mode 100644 index 0000000..075d1ae --- /dev/null +++ b/public/public/Nacelle/SIL Open Font License.txt @@ -0,0 +1,91 @@ +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/public/public/RobotoCondensed/LICENSE.txt b/public/public/RobotoCondensed/LICENSE.txt new file mode 100644 index 0000000..75b5248 --- /dev/null +++ b/public/public/RobotoCondensed/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/public/public/RobotoCondensed/RobotoCondensed-Bold.ttf b/public/public/RobotoCondensed/RobotoCondensed-Bold.ttf new file mode 100644 index 0000000..8c7a08b Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-Bold.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-BoldItalic.ttf b/public/public/RobotoCondensed/RobotoCondensed-BoldItalic.ttf new file mode 100644 index 0000000..83e8a93 Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-BoldItalic.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-Italic.ttf b/public/public/RobotoCondensed/RobotoCondensed-Italic.ttf new file mode 100644 index 0000000..a7fcb3f Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-Italic.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-Light.ttf b/public/public/RobotoCondensed/RobotoCondensed-Light.ttf new file mode 100644 index 0000000..67e8408 Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-Light.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-LightItalic.ttf b/public/public/RobotoCondensed/RobotoCondensed-LightItalic.ttf new file mode 100644 index 0000000..8e2d6c0 Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-LightItalic.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-Medium.ttf b/public/public/RobotoCondensed/RobotoCondensed-Medium.ttf new file mode 100644 index 0000000..4dfbac9 Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-Medium.ttf differ diff --git a/public/public/RobotoCondensed/RobotoCondensed-Regular.ttf b/public/public/RobotoCondensed/RobotoCondensed-Regular.ttf new file mode 100644 index 0000000..533e399 Binary files /dev/null and b/public/public/RobotoCondensed/RobotoCondensed-Regular.ttf differ diff --git a/public/public/fonts.css b/public/public/fonts.css index e8e8c97..0883ed1 100644 --- a/public/public/fonts.css +++ b/public/public/fonts.css @@ -1,176 +1,143 @@ -/* cyrillic-ext */ + +/* Thin */ @font-face { - font-family: 'Roboto Flex'; - font-style: normal; + font-family: 'Nacelle'; font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + font-style: normal; + src: url(/public/Nacelle/Nacelle-Thin.otf) format('opentype'); } -/* cyrillic */ + +/* Thin Italic */ @font-face { - font-family: 'Roboto Flex'; - font-style: normal; + font-family: 'Nacelle'; font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + font-style: italic; + src: url(/public/Nacelle/Nacelle-ThinItalic.otf) format('opentype'); } -/* greek */ + +/* Ultra Light */ @font-face { - font-family: 'Roboto Flex'; + font-family: 'Nacelle'; + font-weight: 200; font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; + src: url(/public/Nacelle/Nacelle-UltraLight.otf) format('opentype'); } -/* vietnamese */ + +/* Ultra Light Italic */ @font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; + font-family: 'Nacelle'; + font-weight: 200; + font-style: italic; + src: url(/public/Nacelle/Nacelle-UltraLightItalic.otf) format('opentype'); } -/* latin-ext */ + +/* Light */ @font-face { - font-family: 'Roboto Flex'; + font-family: 'Nacelle'; + font-weight: 300; font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; + src: url(/public/Nacelle/Nacelle-Light.otf) format('opentype'); } + +/* Light Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 300; + font-style: italic; + src: url(/public/Nacelle/Nacelle-LightItalic.otf) format('opentype'); +} + +/* Regular */ +@font-face { + font-family: 'Nacelle'; + font-weight: 400; + font-style: normal; + src: url(/public/Nacelle/Nacelle-Regular.otf) format('opentype'); +} + +/* Regular Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 400; + font-style: italic; + src: url(/public/Nacelle/Nacelle-Italic.otf) format('opentype'); +} + +/* Semi-Bold */ +@font-face { + font-family: 'Nacelle'; + font-weight: 600; + font-style: normal; + src: url(/public/Nacelle/Nacelle-SemiBold.otf) format('opentype'); +} + +/* Semi-Bold Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 600; + font-style: italic; + src: url(/public/Nacelle/Nacelle-SemiBoldItalic.otf) format('opentype'); +} + +/* Bold */ +@font-face { + font-family: 'Nacelle'; + font-weight: 700; + font-style: normal; + src: url(/public/Nacelle/Nacelle-Bold.otf) format('opentype'); +} + +/* Bold Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 700; + font-style: italic; + src: url(/public/Nacelle/Nacelle-BoldItalic.otf) format('opentype'); +} + +/* Heavy */ +@font-face { + font-family: 'Nacelle'; + font-weight: 800; + font-style: normal; + src: url(/public/Nacelle/Nacelle-Heavy.otf) format('opentype'); +} + +/* Heavy Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 800; + font-style: italic; + src: url(/public/Nacelle/Nacelle-HeavyItalic.otf) format('opentype'); +} + +/* Black */ +@font-face { + font-family: 'Nacelle'; + font-weight: 900; + font-style: normal; + src: url(/public/Nacelle/Nacelle-Black.otf) format('opentype'); +} + +/* Black Italic */ +@font-face { + font-family: 'Nacelle'; + font-weight: 900; + font-style: italic; + src: url(/public/Nacelle/Nacelle-BlackItalic.otf) format('opentype'); +} + + +@font-face { + font-family: 'Roboto Condensed'; + font-weight: 500; + font-style: normal; + src: url(/public/RobotoCondensed/RobotoCondensed-Medium.ttf) format('truetype'); +} + /* latin */ @font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 100; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-EmFw.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-wmF9lp.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; -} -/* cyrillic */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-UmF9lp.woff2) format('woff2'); - unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-ImF9lp.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-4mF9lp.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Roboto Flex'; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - font-display: block; - src: url(/public/NaNeepOXO_NexZs0b5QrzlOHb8wCikXpYqmZsWI-__OGfttPZktqc2VdZ80KvCLZaPcSBZtOx2MifRuWR28sPJtUMbsFEK6cRrleUx9Xgbm3WLHa_F4Ep4Fm0PN19Ik5Dntczx0wZGzhPlL1YNMYKbv9_1IQXOw7AiUJVXRrV8cWW4O8LJCoXjCnwSRSaLshNP1d9-8mF9lp.woff2) format('woff2'); - unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Roboto Flex'; + font-family: 'Roboto Black'; font-style: normal; font-weight: 700; font-stretch: 100%; diff --git a/src/assets/icons/ellipsis.svg b/src/assets/icons/ellipsis.svg new file mode 100644 index 0000000..2efcfee --- /dev/null +++ b/src/assets/icons/ellipsis.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/feed_reply.svg b/src/assets/icons/feed_reply.svg index 2f254a0..195f7fe 100644 --- a/src/assets/icons/feed_reply.svg +++ b/src/assets/icons/feed_reply.svg @@ -1,3 +1,10 @@ - + + + + + + + + diff --git a/src/assets/icons/feed_reply_fill.svg b/src/assets/icons/feed_reply_fill.svg index 2964b56..a15a5da 100644 --- a/src/assets/icons/feed_reply_fill.svg +++ b/src/assets/icons/feed_reply_fill.svg @@ -1,3 +1,10 @@ - + + + + + + + + diff --git a/src/assets/icons/feed_reply_fill_old.svg b/src/assets/icons/feed_reply_fill_old.svg new file mode 100644 index 0000000..2964b56 --- /dev/null +++ b/src/assets/icons/feed_reply_fill_old.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/feed_reply_old.svg b/src/assets/icons/feed_reply_old.svg new file mode 100644 index 0000000..2f254a0 --- /dev/null +++ b/src/assets/icons/feed_reply_old.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/home.svg b/src/assets/icons/home.svg index 5843407..9f8f29c 100644 --- a/src/assets/icons/home.svg +++ b/src/assets/icons/home.svg @@ -1,4 +1,3 @@ - - - + + diff --git a/src/assets/icons/home_fill.svg b/src/assets/icons/home_fill.svg new file mode 100644 index 0000000..e089db8 --- /dev/null +++ b/src/assets/icons/home_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/reply.svg b/src/assets/icons/reply.svg deleted file mode 100644 index 3179623..0000000 --- a/src/assets/icons/reply.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/icons/reply_filled.svg b/src/assets/icons/reply_filled.svg deleted file mode 100644 index b34b012..0000000 --- a/src/assets/icons/reply_filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/icons/search.svg b/src/assets/icons/search.svg index 8390f42..96c2052 100644 --- a/src/assets/icons/search.svg +++ b/src/assets/icons/search.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/assets/icons/search_filled.svg b/src/assets/icons/search_filled.svg index 2df437e..2657729 100644 --- a/src/assets/icons/search_filled.svg +++ b/src/assets/icons/search_filled.svg @@ -1,4 +1,11 @@ - - - + + + + + + + + + + diff --git a/src/assets/icons/send.svg b/src/assets/icons/send.svg new file mode 100644 index 0000000..913dd69 --- /dev/null +++ b/src/assets/icons/send.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/AddToHomeFeedButton/AddToHomeFeedButton.module.scss b/src/components/AddToHomeFeedButton/AddToHomeFeedButton.module.scss index 1e53edd..35f2198 100644 --- a/src/components/AddToHomeFeedButton/AddToHomeFeedButton.module.scss +++ b/src/components/AddToHomeFeedButton/AddToHomeFeedButton.module.scss @@ -2,10 +2,9 @@ display: flex; position: absolute; bottom: 0px; - width: 100%; height: 35px; justify-content: flex-end; - align-items: flex-end; + align-items: center; .noAdd { display: flex; diff --git a/src/components/Avatar/Avatar.module.scss b/src/components/Avatar/Avatar.module.scss index 0d37978..77ae426 100644 --- a/src/components/Avatar/Avatar.module.scss +++ b/src/components/Avatar/Avatar.module.scss @@ -20,7 +20,7 @@ height: 15px; display: inline-block; margin: 0px 0px; - background-color: var(--accent-2); + background-color: var(--accent); -webkit-mask: url(../../assets/icons/verified.svg) no-repeat 0px / 15px; mask: url(../../assets/icons/verified.svg) no-repeat 0px / 15px; } @@ -85,6 +85,23 @@ } } +.vvsAvatar { + @include avatar; + width: 36px; + height: 36px; + + .missingBack { + width: 36px; + height: 36px; + } + + .iconBackground { + @include iconBackground; + bottom: -6px; + right: -6px; + } +} + .vsAvatar { @include avatar; width: 42px; @@ -221,6 +238,13 @@ font-size: 10px; } +.vvsMissing { + @include missing; + width: 36px; + height: 36px; + font-size: 10px; +} + .vsMissing { @include missing; width: 42px; @@ -264,8 +288,8 @@ } .highlightBorder { - background: var(--brand-gradient); - padding: 2px; + background: none; + // padding: 2px; } .cacheFlag { diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx index e9a6ef7..af53f6f 100644 --- a/src/components/Avatar/Avatar.tsx +++ b/src/components/Avatar/Avatar.tsx @@ -10,7 +10,7 @@ import styles from './Avatar.module.scss'; const Avatar: Component<{ src?: string | undefined, - size?: "xxs" | "xss" | "xs" | "vs" | "sm" | "md" | "lg" | "xl" | "xxl", + size?: "xxs" | "xss" | "xs" | "vvs" | "vs" | "sm" | "md" | "lg" | "xl" | "xxl", user?: PrimalUser, highlightBorder?: boolean, id?: string, @@ -28,6 +28,7 @@ const Avatar: Component<{ xxs: styles.xxsAvatar, xss: styles.xssAvatar, xs: styles.xsAvatar, + vvs: styles.vvsAvatar, vs: styles.vsAvatar, sm: styles.smallAvatar, md: styles.midAvatar, @@ -40,6 +41,7 @@ const Avatar: Component<{ xxs: styles.xxsMissing, xss: styles.xssMissing, xs: styles.xsMissing, + vvs: styles.vvsMissing, vs: styles.vsMissing, sm: styles.smallMissing, md: styles.midMissing, @@ -71,6 +73,7 @@ const Avatar: Component<{ case 'xxs': case 'xss': case 'xs': + case 'vvs': case 'vs': case 'sm': case 'md': diff --git a/src/components/Branding/Branding.module.scss b/src/components/Branding/Branding.module.scss index 2b2aec0..a4a8f8c 100644 --- a/src/components/Branding/Branding.module.scss +++ b/src/components/Branding/Branding.module.scss @@ -11,6 +11,7 @@ span { // margin-right: 12px; + font-family: "Roboto Black"; font-weight: 700; font-size: 30px; line-height: 30px; diff --git a/src/components/Branding/Branding.tsx b/src/components/Branding/Branding.tsx index 6ef42a2..6aa3221 100644 --- a/src/components/Branding/Branding.tsx +++ b/src/components/Branding/Branding.tsx @@ -6,42 +6,40 @@ import { useIntl } from '@cookbook/solid-intl'; import { branding } from '../../translations'; import PageNav from '../PageNav/PageNav'; -const Branding: Component<{ small?: boolean, isHome?: boolean, showNav?: boolean }> = (props) => { +const Branding: Component<{ small?: boolean, isHome?: boolean }> = (props) => { const navigate = useNavigate(); const intl = useIntl(); - const onClick = () => { + const toHomeOrScrollToTop = () => { if (props.isHome) { window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); return; } - navigate('/home'); + navigate('/'); } return ( - }> -
-
- } - > -
+ - + } + > +
+
+ + {intl.formatMessage(branding)} + +
+ + ) } diff --git a/src/components/Buttons/ButtonFlip.tsx b/src/components/Buttons/ButtonFlip.tsx new file mode 100644 index 0000000..1f5c896 --- /dev/null +++ b/src/components/Buttons/ButtonFlip.tsx @@ -0,0 +1,40 @@ +import { Component, JSXElement, Match, Show, Switch } from 'solid-js'; +import { hookForDev } from '../../lib/devTools'; +import { Button } from "@kobalte/core"; + +import styles from './Buttons.module.scss'; + +const ButtonFollow: Component<{ + id?: string, + onClick?: (e: MouseEvent) => void, + when?: boolean, + children?: JSXElement, + fallback?: JSXElement, + disabled?: boolean, + type?: 'button' | 'submit' | 'reset' | undefined, +}> = (props) => { + const klass = () => { + return props.when ? styles.flipActive : styles.flipInactive; + } + + return ( + + + + {props.children} + + + + ) +} + +export default hookForDev(ButtonFollow); diff --git a/src/components/Buttons/ButtonFollow.tsx b/src/components/Buttons/ButtonFollow.tsx deleted file mode 100644 index 8224d12..0000000 --- a/src/components/Buttons/ButtonFollow.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useIntl } from '@cookbook/solid-intl'; -import { Button } from '@kobalte/core'; -import { Component, Show } from 'solid-js'; -import { useAccountContext } from '../../contexts/AccountContext'; -import { hookForDev } from '../../lib/devTools'; -import { account as t, actions } from '../../translations'; -import { PrimalUser } from '../../types/primal'; -import { useToastContext } from '../Toaster/Toaster'; - -import styles from './Buttons.module.scss'; - - -const ButtonFollow: Component<{ - person: PrimalUser | undefined, - id?: string, - onFollow?: (person: PrimalUser | undefined) => void, - then?: (remove: boolean, pubkey: string) => void, -}> = (props) => { - - const toast = useToastContext() - const account = useAccountContext(); - const intl = useIntl(); - - const isFollowed = () => { - return props.person && - account?.publicKey && - account?.following.includes(props.person.pubkey); - } - - const onFollow = (e: MouseEvent) => { - e.preventDefault(); - if (props.onFollow) { - props.onFollow(props.person); - return - } - - - if (!account || !account.hasPublicKey() || !props.person) { - account?.actions.showGetStarted(); - // toast?.sendWarning(intl.formatMessage(t.needToLogin)) - return; - } - - const action = isFollowed() ? - account.actions.removeFollow : - account.actions.addFollow; - - action(props.person.pubkey, props.then); - } - - const klass = () => { - return isFollowed() ? styles.unfollow : styles.follow; - } - - return ( - - - - {intl.formatMessage(t.unfollow)} - - - - ) -} - -export default hookForDev(ButtonFollow); diff --git a/src/components/Buttons/ButtonPrimary.tsx b/src/components/Buttons/ButtonPrimary.tsx index 6e26c68..415be7c 100644 --- a/src/components/Buttons/ButtonPrimary.tsx +++ b/src/components/Buttons/ButtonPrimary.tsx @@ -9,6 +9,7 @@ const ButtonPrimary: Component<{ onClick?: (e: MouseEvent) => void, children?: JSXElement, disabled?: boolean, + type?: 'button' | 'submit' | 'reset' | undefined, }> = (props) => { return ( - - {props.children} - + {props.children} ) } diff --git a/src/components/Buttons/ButtonSecondary.tsx b/src/components/Buttons/ButtonSecondary.tsx index e35812a..5bfe5fe 100644 --- a/src/components/Buttons/ButtonSecondary.tsx +++ b/src/components/Buttons/ButtonSecondary.tsx @@ -9,19 +9,32 @@ const ButtonSecondary: Component<{ onClick?: (e: MouseEvent) => void, children?: JSXElement, disabled?: boolean, + shrink?: boolean, + light?: boolean, + type?: 'button' | 'submit' | 'reset' | undefined, }> = (props) => { + + const klass = () => { + let cls = styles.secondary; + + if (props.shrink) + cls += ` ${styles.shrunk}`; + + if (props.light) + cls += ` ${styles.light}`; + + return cls; + } + return ( -
- - {props.children} - -
+ {props.children}
); } diff --git a/src/components/Buttons/Buttons.module.scss b/src/components/Buttons/Buttons.module.scss index 762ef0e..7f799e1 100644 --- a/src/components/Buttons/Buttons.module.scss +++ b/src/components/Buttons/Buttons.module.scss @@ -1,44 +1,46 @@ .primary { + display: flex; + justify-content: center; + align-items: center; border: none; - border-radius: 6px; - margin: 0px 8px; - padding-inline: 10px; - padding-block: 6px; - font-size: 14px; - line-height: 20px; - font-weight: 700; - background: var(--brand-gradient-vertical); - color: white; - >span { - opacity: 0.75; - } + border-radius: 99999px; + margin: 0px; + padding-inline: 18px; + padding-block: 10px; + font-size: 16px; + line-height: 16px; + font-weight: 600; + background: var(--accent); + color: var(--text-primary-button); + width: fit-content; + min-height: 36px; } .secondary { + display: flex; + justify-content: center; + align-items: center; border: none; - border-radius: 6px; - padding: 1px; - font-size: 14px; - line-height: 20px; - font-weight: 700; - background: var(--brand-gradient-vertical); - color: var(--text-tertiary-2); - >div { - width: 100%; - height: 100%; - vertical-align: middle; - border-radius: 6px; - background-color: var(--background-card); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding-inline: 10px; - padding-block: 6px; + border-radius: 99999px; + margin: 0px; + padding-inline: 38px; + font-size: 16px; + line-height: 16px; + font-weight: 600; + background: var(--background-input); + color: var(--text-secondary); + width: fit-content; + height: 36px; + + &.light { + background-color: var(--subtile-devider); } } - +.shrunk { + padding-inline: 0; + min-width: 36px; +} .copy { .copyIcon { @@ -64,7 +66,7 @@ color: var(--text-tertiary-2); font-size: 14px; font-weight: 400; - line-height: 12px; + line-height: 16px; background: none; margin: 0; padding: 0; @@ -113,52 +115,44 @@ } } -.follow { +.flipInactive { display: flex; - align-items: center; justify-content: center; - width: fit-content; - height: fit-content; - min-width: 96px; + align-items: center; border: none; - border-radius: 6px; + border-radius: 99999px; margin: 0px; - padding: 10px; + padding-inline: 18px; + padding-block: 10px; font-size: 16px; - line-height: 20px; - font-weight: 700; + line-height: 16px; + font-weight: 600; background: var(--text-primary); color: var(--background-site); - - &:hover { - color: var(--subtile-devider); - } + width: fit-content; &:focus { box-shadow: none; } } -.unfollow { +.flipActive { display: flex; align-items: center; justify-content: center; width: fit-content; height: fit-content; - min-width: 96px; + border-radius: 99999px; border: none; - border-radius: 6px; margin: 0px; - padding: 10px; + padding-inline: 18px; + padding-block: 10px; font-size: 16px; line-height: 20px; font-weight: 700; background: var(--background-input); color: var(--text-primary); - - &:hover { - background-color: var(--subtile-devider); - } + width: fit-content; &:focus { box-shadow: none; @@ -175,11 +169,11 @@ border-radius: 6px; margin: 0px; padding: 0px; - font-size: 16px; + font-size: 15px; line-height: 20px; - font-weight: 700; + font-weight: 400; background: none; - color: var(--accent-1); + color: var(--accent); &:hover { text-decoration: underline; @@ -191,18 +185,18 @@ } .tertiary { - border-radius: 6px; - padding-inline: 10px; - padding-block: 6px; - font-size: 12px; - line-height: 16px; - font-weight: 700; - margin: 0px; - color: var(--text-primary); - background: var(--background-card); - border: 1px solid var(--subtile-devider); + border-radius: 6px; + padding-inline: 10px; + padding-block: 6px; + font-size: 12px; + line-height: 16px; + font-weight: 700; + margin: 0px; + color: var(--text-primary); + background: var(--background-card); + border: 1px solid var(--subtile-devider); - &:hover { - border: 1px solid var(--text-tertiary); - } + &:hover { + border: 1px solid var(--text-tertiary); + } } diff --git a/src/components/ConfirmModal/ConfirmModal.module.scss b/src/components/ConfirmModal/ConfirmModal.module.scss index e1d711c..b20f9d4 100644 --- a/src/components/ConfirmModal/ConfirmModal.module.scss +++ b/src/components/ConfirmModal/ConfirmModal.module.scss @@ -4,10 +4,7 @@ position: fixed; width: 420px; color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), - var(--background-site)) padding-box, - var(--brand-gradient) border-box; + background-color: var(--background-input); border: 1px solid transparent; border-radius: 6px; @@ -36,6 +33,10 @@ display: flex; justify-content: space-between; + >button { + min-width: 178px; + } + .feedRestoreConfirm { background: var(--brand-gradient-vertical); border: none; diff --git a/src/components/ConfirmModal/ConfirmModal.tsx b/src/components/ConfirmModal/ConfirmModal.tsx index 09b638a..ad4b4a1 100644 --- a/src/components/ConfirmModal/ConfirmModal.tsx +++ b/src/components/ConfirmModal/ConfirmModal.tsx @@ -14,6 +14,8 @@ import { confirmDefaults as t } from '../../translations'; import styles from './ConfirmModal.module.scss'; import { hookForDev } from '../../lib/devTools'; +import ButtonPrimary from '../Buttons/ButtonPrimary'; +import ButtonSecondary from '../Buttons/ButtonSecondary'; const ConfirmModal: Component<{ id?: string, @@ -39,21 +41,20 @@ const ConfirmModal: Component<{
- + {props.confirmLabel || intl.formatMessage(t.confirm)} + - + {props.abortLablel || intl.formatMessage(t.abort)} +
diff --git a/src/components/CreateAccountModal/CreateAccountModal.module.scss b/src/components/CreateAccountModal/CreateAccountModal.module.scss index e76dd91..b5a68a3 100644 --- a/src/components/CreateAccountModal/CreateAccountModal.module.scss +++ b/src/components/CreateAccountModal/CreateAccountModal.module.scss @@ -1,17 +1,13 @@ .modal { position: fixed; - width: 420px; + width: 440px; color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), - var(--background-site)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - border-radius: 6px; + background-color: var(--background-input); + border-radius: 8px; display: flex; flex-direction: column; - padding: 22px; + padding: 24px; .xClose { background: none; @@ -46,17 +42,16 @@ } .title { - font-weight: 800; font-size: 18px; - line-height: 18px; - color: var(--text-secondary); - text-transform: uppercase; + font-weight: 600; + line-height: 20px; + color: var(--text-primary); margin-bottom: 20px; } .description { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; line-height: 20px; margin-bottom: 28px; @@ -69,16 +64,18 @@ button { width: fit-content; - padding: 10px; + padding-block: 10px; + padding-inline: 30px; margin: 0px; } } .alternative { - color: var(--text-secondary); - font-size: 14px; + color: var(--text-primary); + font-size: 15px; + font-style: normal; font-weight: 400; - line-height: 24px; + line-height: 20px; } } diff --git a/src/components/CreatePinModal/CreatePinModal.module.scss b/src/components/CreatePinModal/CreatePinModal.module.scss index a0d5ef0..74d6c2a 100644 --- a/src/components/CreatePinModal/CreatePinModal.module.scss +++ b/src/components/CreatePinModal/CreatePinModal.module.scss @@ -1,17 +1,13 @@ .modal { position: fixed; - width: 452px; - color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), - var(--background-site)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - border-radius: 6px; + width: 440px; + color: var(--text-primary); + background-color: var(--background-input); + border-radius: 8px; display: flex; flex-direction: column; - padding: 22px; + padding: 24px; .xClose { background: none; @@ -46,49 +42,45 @@ } .title { - font-weight: 800; font-size: 18px; - line-height: 18px; - color: var(--text-secondary); - text-transform: uppercase; + font-weight: 600; + line-height: 20px; + color: var(--text-primary); margin-bottom: 20px; } .description { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; line-height: 20px; margin-bottom: 28px; } .inputs { - margin-bottom: 4px; - > div { - margin-bottom: 4px; + .description { + margin-bottom: 20px; } } .actions { display: flex; justify-content: space-between; - margin-bottom: 20px; button { width: fit-content; - min-width: 192px; + padding-block: 10px; + padding-inline: 36px; margin: 0px; - >div { - padding: 10px; - } } } .alternative { - color: var(--text-secondary); - font-size: 14px; + color: var(--text-primary); + font-size: 15px; + font-style: normal; font-weight: 400; - line-height: 24px; + line-height: 20px; } } diff --git a/src/components/CreatePinModal/CreatePinModal.tsx b/src/components/CreatePinModal/CreatePinModal.tsx index cde1760..47cb877 100644 --- a/src/components/CreatePinModal/CreatePinModal.tsx +++ b/src/components/CreatePinModal/CreatePinModal.tsx @@ -83,26 +83,29 @@ const CreatePinModal: Component<{
{intl.formatMessage(tPin.description)}
-
- setPin(val)} - validationState={pin().length === 0 || isValidPin() ? 'valid' : 'invalid'} - errorMessage={intl.formatMessage(tPin.invalidPin)} - /> - setRePin(val)} - label={intl.formatMessage(tPin.reEnter)} - validationState={rePin().length === 0 || isValidRePin() ? 'valid' : 'invalid'} - errorMessage={intl.formatMessage(tPin.invalidRePin)} - /> + + setPin(val)} + validationState={pin().length === 0 || isValidPin() ? 'valid' : 'invalid'} + errorMessage={intl.formatMessage(tPin.invalidPin)} + /> + +
+ {intl.formatMessage(tPin.reEnter)}
+ setRePin(val)} + validationState={rePin().length === 0 || isValidRePin() ? 'valid' : 'invalid'} + errorMessage={intl.formatMessage(tPin.invalidRePin)} + /> +
{intl.formatMessage(tActions.optoutPin)} diff --git a/src/components/CustomZap/CustomZap.module.scss b/src/components/CustomZap/CustomZap.module.scss index a5d0ad0..e95d8e4 100644 --- a/src/components/CustomZap/CustomZap.module.scss +++ b/src/components/CustomZap/CustomZap.module.scss @@ -1,22 +1,19 @@ .customZap { position: fixed; - width: 420px; - height: 285px; - color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), var(--background-site)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - border-radius: 6px; + width: 432px; + color: var(--text-primary); + background-color: var(--background-input); + border-radius: 8px; display: flex; flex-direction: column; - padding: 22px; + padding: 20px; .header { display: flex; flex-direction: row; justify-content: space-between; + margin-bottom: 24px; .title { display: flex; @@ -28,13 +25,13 @@ font-size: 18px; line-height: 18px; color: var(--text-secondary); - text-transform: uppercase; .amount { color: var(--text-primary); } .units { + margin-left: 8px; font-weight: 800; font-size: 12px; line-height: 20px; @@ -62,28 +59,71 @@ } } + .description { + color: var(--text-secondary); + font-size: 17px; + font-weight: 600; + line-height: 24px; + + + .amount { + color: var(--text-primary); + font-size: 20px; + font-weight: 600; + line-height: 24px; + } + + .units { + margin-left: 4px; + } + } + .options { display: grid; - grid-template-columns: 1fr 1fr 1fr; + grid-template-columns: 120px 120px 120px; grid-column-gap: 12px; - grid-row-gap: 16px; + grid-row-gap: 12px; margin-top: 24px; + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 1px solid var(--subtile-devider); .zapOption { - height: 40px; - border-radius: 20px; + width: 120px; + height: 36px; + border-radius: 18px; border: none; outline: none; padding: 0; + padding-top: 4px; + padding-left: 16px; margin: 0; box-shadow: none; - background-color: var(--background-input); + background-color: var(--background-header-input); color: var(--text-primary); - text-transform: uppercase; + font-size: 16px; + font-weight: 600; + line-height: 20px; + + display: flex; + justify-content: flex-start; + align-items: center; + + .sats { + color: var(--text-tertiary); + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 20px; + } &.selected, &:hover { background-color: var(--text-primary); color: var(--background-site); + + .sats { + color: var(--text-tertiary-2); + } } } @@ -96,12 +136,10 @@ border-radius: 6px; background-color: var(--background-site); color: var(--text-secondary); - padding-block: 6px; padding-inline: 13px; font-weight: 400; font-size: 14px; line-height: 20px; - margin-top: 16px; &::placeholder { color: var(--subtile-devider); @@ -113,19 +151,10 @@ } .action { - width: 100%; - height: 32px; - background: var(--brand-gradient-vertical); - border: none; - outline: none; - padding: 0; - margin: 0; - box-shadow: none; - .caption { - font-weight: 700; - font-size: 14px; - line-height: 20px; - color: white; + margin-top: 24px; + >button { + width: 100%; + height: 38px; } } diff --git a/src/components/CustomZap/CustomZap.tsx b/src/components/CustomZap/CustomZap.tsx index c517869..81b89c7 100644 --- a/src/components/CustomZap/CustomZap.tsx +++ b/src/components/CustomZap/CustomZap.tsx @@ -5,10 +5,12 @@ import { useSettingsContext } from '../../contexts/SettingsContext'; import { hookForDev } from '../../lib/devTools'; import { zapNote } from '../../lib/zap'; import { userName } from '../../stores/profile'; -import { toastZapFail, zapCustomOption } from '../../translations'; +import { toastZapFail, zapCustomOption, actions as tActions, placeholders as tPlaceholders } from '../../translations'; import { PrimalNote } from '../../types/primal'; import { debounce } from '../../utils'; +import ButtonPrimary from '../Buttons/ButtonPrimary'; import Modal from '../Modal/Modal'; +import TextInput from '../TextInput/TextInput'; import { useToastContext } from '../Toaster/Toaster'; import styles from './CustomZap.module.scss'; @@ -28,6 +30,7 @@ const CustomZap: Component<{ const settings = useSettingsContext(); const [selectedValue, setSelectedValue] = createSignal(settings?.availableZapOptions[0] || 10); + const [comment, setComment] = createSignal(''); createEffect(() => { setSelectedValue(settings?.availableZapOptions[0] || 10) @@ -35,15 +38,6 @@ const CustomZap: Component<{ const isSelected = (value: number) => value === selectedValue(); - let comment = ''; - - const setComment = (e: InputEvent) => { - debounce(() => { - const target = e.target as HTMLInputElement; - comment = target.value; - }, 500); - }; - const truncateNumber = (amount: number) => { const t = 1000; @@ -81,7 +75,13 @@ const CustomZap: Component<{ const submit = async () => { if (account?.hasPublicKey()) { props.onConfirm(selectedValue()); - const success = await zapNote(props.note, account.publicKey, selectedValue(), comment, account.relays); + const success = await zapNote( + props.note, + account.publicKey, + selectedValue(), + comment(), + account.relays, + ); if (success) { props.onSuccess(selectedValue()); @@ -101,20 +101,25 @@ const CustomZap: Component<{
-
- {intl.formatMessage(zapCustomOption,{ - user: userName(props.note.user), - })} - - {truncateNumber(selectedValue())} - sats + {intl.formatMessage(tActions.zap)}
+
+ {intl.formatMessage(zapCustomOption,{ + user: userName(props.note.user), + })} + + + {truncateNumber(selectedValue())} + + sats +
+
{(value) => @@ -122,33 +127,33 @@ const CustomZap: Component<{ class={`${styles.zapOption} ${isSelected(value) ? styles.selected : ''}`} onClick={() => setSelectedValue(value)} > - {truncateNumber(value)} +
+ {truncateNumber(value)} sats +
}
- - + +
+ {intl.formatMessage(tActions.zap)} +
+
+
diff --git a/src/components/EmbeddedNote/EmbeddedNote.module.scss b/src/components/EmbeddedNote/EmbeddedNote.module.scss index dd1d37e..af9162f 100644 --- a/src/components/EmbeddedNote/EmbeddedNote.module.scss +++ b/src/components/EmbeddedNote/EmbeddedNote.module.scss @@ -1,8 +1,8 @@ .mentionedNote { - border: solid 1px var(--border-embedded-card); + border: none; border-radius: 8px; - background-color: var(--background-embedded_card); + background-color: var(--background-input); margin-block: 6px; padding: 18px; display: grid; diff --git a/src/components/EnterPinModal/EnterPinModal.module.scss b/src/components/EnterPinModal/EnterPinModal.module.scss index 17c73f0..d41020d 100644 --- a/src/components/EnterPinModal/EnterPinModal.module.scss +++ b/src/components/EnterPinModal/EnterPinModal.module.scss @@ -1,17 +1,13 @@ .modal { position: fixed; - width: 452px; + width: 440px; color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), - var(--background-site)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - border-radius: 6px; + background-color: var(--background-input); + border-radius: 8px; display: flex; flex-direction: column; - padding: 22px; + padding: 24px; .xClose { background: none; @@ -46,17 +42,16 @@ } .title { - font-weight: 800; font-size: 18px; - line-height: 18px; - color: var(--text-secondary); - text-transform: uppercase; + font-weight: 600; + line-height: 20px; + color: var(--text-primary); margin-bottom: 20px; } .description { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; line-height: 20px; margin-bottom: 28px; diff --git a/src/components/EnterPinModal/EnterPinModal.tsx b/src/components/EnterPinModal/EnterPinModal.tsx index 96ada5c..df88410 100644 --- a/src/components/EnterPinModal/EnterPinModal.tsx +++ b/src/components/EnterPinModal/EnterPinModal.tsx @@ -99,6 +99,9 @@ const EnterPinModal: Component<{
{intl.formatMessage(tPin.enterTitle)}
+
+ {intl.formatMessage(tPin.enter)} +
setPin(val)} - label={intl.formatMessage(tPin.enter)} validationState={pin().length === 0 || isValidPin() ? 'valid' : 'invalid'} errorMessage={intl.formatMessage(tPin.invalidRePin)} /> diff --git a/src/components/ExploreMenuItem/ExploreMenuItem.module.scss b/src/components/ExploreMenuItem/ExploreMenuItem.module.scss index a6daa33..26e13bd 100644 --- a/src/components/ExploreMenuItem/ExploreMenuItem.module.scss +++ b/src/components/ExploreMenuItem/ExploreMenuItem.module.scss @@ -1,12 +1,14 @@ .exploreMenuItem { display: flex; - width: 100%; + width: calc(100% - 2px); height: 100px; background-color: var(--background-card); justify-content: space-between; - padding-left: 24px; - margin-bottom: 16px; - border-radius: 4px; + padding: 10px 20px; + border-radius: 0; + + border-bottom: 1px solid var(--devider); + .itemInfo { display: flex; @@ -25,16 +27,16 @@ .itemCaption { font-size: 18px; + font-weight: 600; line-height: 24px; - font-weight: 700; color: var(--text-primary); margin-right: 12px; } .itemStat { font-size: 24px; + font-weight: 400; line-height: 28px; - font-weight: 300; color: var(--text-primary); } @@ -44,8 +46,8 @@ .itemDescription { font-size: 12px; + font-weight: 400; line-height: 16px; - font-weight: 300; color: var(--text-secondary); } } @@ -60,7 +62,7 @@ .option { width: 72px; - height: 92px; + height: 100%; border: none; margin: 4px; padding: 0px; @@ -71,6 +73,7 @@ flex-direction: column; align-items: center; justify-content: center; + border-radius: var(--border-radius-big); cursor: pointer; >div { @@ -89,11 +92,9 @@ &:hover { outline: none; text-decoration: none; - border: solid 1px var(--subtile-devider); - border-radius: 4px; background-color: var(--background-input); >div { - background: var(--highlight-gradient); + background: var(--accent); } } } diff --git a/src/components/ExploreMenuItem/ExploreMenuItem.tsx b/src/components/ExploreMenuItem/ExploreMenuItem.tsx index fe4969d..eecc919 100644 --- a/src/components/ExploreMenuItem/ExploreMenuItem.tsx +++ b/src/components/ExploreMenuItem/ExploreMenuItem.tsx @@ -2,6 +2,7 @@ import { useIntl } from '@cookbook/solid-intl'; import { A } from '@solidjs/router'; import type { Component } from 'solid-js'; import { hookForDev } from '../../lib/devTools'; +import { interpretLineBreak } from '../../translationHelpers'; import { scopeDescriptors, timeframeDescriptors } from '../../translations'; import { ScopeDescriptor } from '../../types/primal'; @@ -68,7 +69,9 @@ const ExploreMenuItem: Component<{ scope: string, stat: number, id?: string }> =
- {intl.formatMessage(item().description)} + {intl.formatMessage(item().description, { + div: interpretLineBreak, + })}
diff --git a/src/components/FeedSelect/FeedSelect.tsx b/src/components/FeedSelect/FeedSelect.tsx index 57283cc..203771c 100644 --- a/src/components/FeedSelect/FeedSelect.tsx +++ b/src/components/FeedSelect/FeedSelect.tsx @@ -2,8 +2,9 @@ import { Component } from 'solid-js'; import { useHomeContext } from '../../contexts/HomeContext'; import { useSettingsContext } from '../../contexts/SettingsContext'; import { hookForDev } from '../../lib/devTools'; -import { FeedOption, PrimalFeed } from '../../types/primal'; +import { FeedOption, PrimalFeed, SelectionOption } from '../../types/primal'; import SelectBox from '../SelectBox/SelectBox'; +import SelectionBox from '../SelectionBox/SelectionBox'; const FeedSelect: Component<{ isPhone?: boolean, id?: string}> = (props) => { @@ -61,17 +62,15 @@ const FeedSelect: Component<{ isPhone?: boolean, id?: string}> = (props) => { return false; } - const options:() => FeedOption[] = () => { + const options:() => SelectionOption[] = () => { if (settings?.availableFeeds === undefined) { return []; } - return settings.availableFeeds.map(feed => { - return ({ - label: feed.name, - value: `${feed.hex}_${feed.includeReplies}`, - }); - }); + return settings.availableFeeds.map(feed => ({ + label: feed.name, + value: `${feed.hex}_${feed.includeReplies}`, + })); }; const initialValue = () => { @@ -100,11 +99,19 @@ const FeedSelect: Component<{ isPhone?: boolean, id?: string}> = (props) => { } } + const selectedValue = () => { + if (!home?.selectedFeed) + return initialValue(); + + return { label: home.selectedFeed.name, value: `${home.selectedFeed.hex}_${home.selectedFeed.includeReplies}` }; + }; + return ( - diff --git a/src/components/FeedSorter/FeedSorter.module.scss b/src/components/FeedSorter/FeedSorter.module.scss index 5df2144..d500219 100644 --- a/src/components/FeedSorter/FeedSorter.module.scss +++ b/src/components/FeedSorter/FeedSorter.module.scss @@ -3,6 +3,9 @@ padding: 0; border: none; background-color: unset; + display: flex; + justify-content: center; + align-items: center; opacity: 0.7; transition: opacity 0.4s; @@ -20,11 +23,11 @@ .feedItem { width: 100%; height: 40px; - background-color: var(--background-site); - color: var(--text-tertiary); - font-size: 16px; - line-height: 14px; + background-color: var(--background-sheet); + color: var(--active-reply); + font-size: 14px; font-weight: 400; + line-height: 12px; padding-inline: 12px; margin-block: 8px; @@ -34,6 +37,10 @@ justify-content: flex-start; cursor: grab; + &:hover, &:focus { + background-color: var(--background-input); + } + .sortControls { margin-right: 5px; .sortButton { @@ -85,26 +92,30 @@ width: 100%; .feedNameInput { height: 32px; - background-color: var(--background-site); + background-color: var(--background-header-input); color: var(--text-tertiary); font-size: 16px; line-height: 14px; font-weight: 400; margin: 0; + border: none; + box-shadow: none; + outline: none; + border-radius: 16px; } .feedEditControl { position: absolute; top: 2px; - right: 0; - height: 32px; + right: 4px; + height: 28px; display: flex; justify-content: flex-end; align-items: center; >button { @include controlButton(); - width: 32px; - height: 32px; + width: 20px; + height: 28px; } } @@ -122,8 +133,8 @@ } .closeIcon { - width: 20px; - height: 20px; + width: 10px; + height: 10px; display: inline-block; margin: 0px 0px; background-color: var(--text-secondary); @@ -132,8 +143,8 @@ } .checkIcon { - width: 20px; - height: 20px; + width: 14px; + height: 14px; display: inline-block; margin: 0px 0px; background-color: var(--text-secondary); diff --git a/src/components/FloatingNewPostButton/FloatingNewPostButton.tsx b/src/components/FloatingNewPostButton/FloatingNewPostButton.tsx index 7f31720..a3a7fa2 100644 --- a/src/components/FloatingNewPostButton/FloatingNewPostButton.tsx +++ b/src/components/FloatingNewPostButton/FloatingNewPostButton.tsx @@ -1,11 +1,16 @@ import { Component } from "solid-js"; import { useAccountContext } from "../../contexts/AccountContext"; import { hookForDev } from "../../lib/devTools"; +import ButtonPrimary from "../Buttons/ButtonPrimary"; + +import { actions as tActions } from "../../translations"; import styles from "./FloatingNewPostButton.module.scss"; +import { useIntl } from "@cookbook/solid-intl"; const FloatingNewPostButton: Component<{ id?: string }> = (props) => { const account = useAccountContext(); + const intl = useIntl(); const showNewNoteForm = () => { account?.actions?.showNewNoteForm(); @@ -13,13 +18,12 @@ const FloatingNewPostButton: Component<{ id?: string }> = (props) => { return ( - + {intl.formatMessage(tActions.newNote)} + ) } diff --git a/src/components/FollowButton/FollowButton.module.scss b/src/components/FollowButton/FollowButton.module.scss index d141cff..3d279b6 100644 --- a/src/components/FollowButton/FollowButton.module.scss +++ b/src/components/FollowButton/FollowButton.module.scss @@ -1,65 +1,86 @@ - - @mixin followButton { - grid-area: follow; - display: flex; - button { - background: var(--brand-gradient-vertical); - border-radius: 6px; - padding: 0px; - font-size: 12px; - line-height: 16px; - font-weight: 700; - margin: 0px; - } +.large { + button { + width: 100px; + text-transform: lowercase; } +} - .primaryButton { - width: 90px; - height: 40px; +.small { + max-width: 72px; + + button { + max-width: 100%; + height: 28px; + padding-block: 0; + font-size: 12px; + font-weight: 600; + line-height: 12px; + text-transform: lowercase; } +} - .follow { - @include followButton; - button { - color: var(--text-primary); - background: linear-gradient(var(--background-card), var(--background-card)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - &:hover { - background: linear-gradient(var(--background-site), var(--background-site)) padding-box, - var(--brand-gradient) border-box; - } - } - } + // @mixin followButton { + // grid-area: follow; + // display: flex; + // button { + // background: var(--brand-gradient-vertical); + // border-radius: 6px; + // padding: 0px; + // font-size: 12px; + // line-height: 16px; + // font-weight: 700; + // margin: 0px; + // } + // } - .unfollow { - @include followButton; - button { - color: var(--text-primary); - background: var(--background-card); - border: 1px solid var(--subtile-devider); + // .primaryButton { + // width: 90px; + // height: 40px; + // } - &:hover { - border: 1px solid var(--text-tertiary); - } - } - } + // .follow { + // @include followButton; + // button { + // color: var(--text-primary); + // background: linear-gradient(var(--background-card), var(--background-card)) padding-box, + // var(--brand-gradient) border-box; + // border: 1px solid transparent; - .large { - button { - width: 90px; - height: 40px; - margin: 0px 8px; - font-size: 16px; - line-height: 20px; - } + // &:hover { + // background: linear-gradient(var(--background-site), var(--background-site)) padding-box, + // var(--brand-gradient) border-box; + // } + // } + // } - } + // .unfollow { + // @include followButton; + // button { + // color: var(--text-primary); + // background: var(--background-card); + // border: 1px solid var(--subtile-devider); - .small { - button { - width: 64px; - height: 40px; - } - } + // &:hover { + // border: 1px solid var(--text-tertiary); + // } + // } + // } + + // .large { + // button { + // width: 90px; + // height: 40px; + // margin: 0px 8px; + // font-size: 16px; + // line-height: 20px; + // } + + // } + + // .small { + // button { + // width: 64px; + // height: 40px; + // } + // } diff --git a/src/components/FollowButton/FollowButton.tsx b/src/components/FollowButton/FollowButton.tsx index 338e3cb..cb288ce 100644 --- a/src/components/FollowButton/FollowButton.tsx +++ b/src/components/FollowButton/FollowButton.tsx @@ -4,6 +4,8 @@ import { useAccountContext } from '../../contexts/AccountContext'; import { hookForDev } from '../../lib/devTools'; import { account as t, actions } from '../../translations'; import { PrimalUser } from '../../types/primal'; +import ButtonFlip from '../Buttons/ButtonFlip'; +import ButtonFollow from '../Buttons/ButtonFlip'; import { useToastContext } from '../Toaster/Toaster'; import styles from './FollowButton.module.scss'; @@ -42,20 +44,20 @@ const FollowButton: Component<{ } const klass = () => { - return `${isFollowed() ? styles.unfollow : styles.follow} ${props.large ? styles.large : styles.small}`; + return props.large ? styles.large : styles.small; } return (
- + + {intl.formatMessage(t.unfollow)} +
) diff --git a/src/components/HomeHeader/HomeHeader.module.scss b/src/components/HomeHeader/HomeHeader.module.scss index 4b26749..ad81b18 100644 --- a/src/components/HomeHeader/HomeHeader.module.scss +++ b/src/components/HomeHeader/HomeHeader.module.scss @@ -1,13 +1,12 @@ .fullHeader { - display: grid; - height: 120px; - padding-top: 26px; + display: flex; + flex-direction: column; + z-index: var(--z-index-header); } .smallHeader { - display: grid; - height: 32px; - grid-template-rows: 1fr 4px; + position:absolute; + height: 84px; } .smallHeaderMain { @@ -15,7 +14,11 @@ flex-direction: row; justify-content: stretch; align-items: flex-end; + height: 84px; background-color: var(--background-site); + padding-inline: 12px; + border-block: 1px solid var(--devider); + z-index: var(--z-index-header); } .smallHeaderBottomBorder { @@ -46,7 +49,6 @@ } .smallLeft { - width: 100%; flex-grow: 20; flex-shrink: 1; visibility: hidden; @@ -56,16 +58,30 @@ max-width: 50%; flex-grow: 1; margin-bottom: 4px; + margin-left: 8px; // margin: auto; + button { + font-size: 14px; + font-weight: 600; + line-height: 20px; + + div { + width: 12px; + height: 12px; + display: inline-block; + margin-inline: 8px; + background-color: var(--text-secondary); + -webkit-mask: url(/src/assets/icons/caret.svg) no-repeat 0 0/12px 12px; + mask: url(/src/assets/icons/caret.svg) no-repeat 0 0/12px 12px; + } + } } .fixedSelector { position:fixed; top: 0px; - width: 640px; - height: 48px; - // align-items: center; - // background-color: var(--background-site); + width: calc(var(--central-content-width) - 2px); + height: var(--header-height); z-index: var(--z-index-header); transition: 0.3s; transform: translateY(0px); @@ -85,52 +101,81 @@ .hiddenSelector { transition: 0.3s; - transform: translateY(-48px); + transform: translateY(-134px); } .instaHide { - top: -48px; + display: none +} + +.bigFeedSelect { + display: flex; + align-items: center; + justify-content: space-between; + background-color: unset; + margin: 0px; + outline: none; + width: 100%; + + padding-block: 10px; + padding-inline: 14px; + border-bottom: 1px solid var(--devider); + z-index: var(--z-index-header); + + + .newContentItem { + color: var(--accent-links); + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 15px; + background: none; + border: none; + box-shadow: none; + outline: none; + width: fit-content; + margin: 0; + padding: 0; + } +} + +.feedPlaceholder { + width: 600px; + height: 20px; + background-color: red; } .callToAction { - display: grid; - height: 72px; - grid-template-columns: 72px 1fr; - grid-column-gap: 17px; + display: flex; align-items: center; + justify-content: flex-start; background-color: unset; margin: 0px; - padding: 0px; - border: none; outline: none; - p { - font-size: 34px; - line-height: 34px; - padding: 0px; - margin: 0px; - } - - .border { - height: 36px; - padding: 1px; - background: var(--brand-gradient); - border-radius: 6px; - margin-left: 10px - } + padding-block: 21px; + padding-inline: 12px; + border: none; + border-bottom: 1px solid var(--devider); + border-radius: 0; + justify-content: flex-start; .input { - height: 34px; - font-size: 18px; + width: 100%; + height: 36px; + font-size: 16px; + font-weight: 400; line-height: 20px; margin: 0px; - border-radius: 6px; + margin-left: 8px; + border-radius: 18px; border: none; color: var(--text-tertiary); - background-color: var(--background-site); + background-color: var(--background-header-input); display: flex; align-items: center; - padding-left: 12px; + justify-content: flex-start; + padding-inline: 16px; } } @@ -138,12 +183,13 @@ display: flex; justify-content: space-between; align-items: center; - height: 72px; - font-weight: 300; + font-weight: 400; font-size: 32px; line-height: 34px; color: var(--brand-text); - text-transform: lowercase; + padding-block: 24px; + padding-inline: 12px; + border-block: 1px solid var(--devider); button { width: fit-content; @@ -155,13 +201,58 @@ .welcomeMessageSmall { display: grid; align-content: center; - font-weight: 300; + font-weight: 400; font-size: 24px; line-height: 28px; color: var(--brand-text); text-transform: lowercase; } +.newContentNotification { + width: var(--central-content-width); + z-index: 20; + display: flex; + justify-content: center; + + >button { + display: flex; + align-items: center; + justify-content: center; + width: auto; + height: 40px; + color: var(--text-primary-button); + background: var(--accent); + font-size: 14px; + font-weight: 400; + line-height: 18px; + border: none; + border-radius: 20px; + padding-block: 0; + padding-left: 4px; + margin: 0; + text-transform: lowercase; + + .avatars { + display: flex; + align-items: center; + height: 40px; + .avatar { + border: solid 2px var(--text-primary-button); + border-radius: 50%; + width: 30px; + height: 30px; + transition: margin-right 0.2s; + margin-right: -9px; + } + } + + .counter { + margin-left: 24px; + } + } + +} + @media only screen and (max-width: 720px) { .fullHeader { width: 100%; diff --git a/src/components/HomeHeader/HomeHeader.tsx b/src/components/HomeHeader/HomeHeader.tsx index f22e52c..ecad786 100644 --- a/src/components/HomeHeader/HomeHeader.tsx +++ b/src/components/HomeHeader/HomeHeader.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal, onCleanup, onMount, Show } from 'solid-js'; +import { Component, createSignal, For, onCleanup, onMount, Show } from 'solid-js'; import Avatar from '../Avatar/Avatar'; import styles from './HomeHeader.module.scss'; @@ -8,24 +8,34 @@ import SmallCallToAction from '../SmallCallToAction/SmallCallToAction'; import { useHomeContext } from '../../contexts/HomeContext'; import { useIntl } from '@cookbook/solid-intl'; import { useSettingsContext } from '../../contexts/SettingsContext'; -import { placeholders as t, actions as tActions } from '../../translations'; +import { placeholders as t, actions as tActions, feedNewPosts } from '../../translations'; import { hookForDev } from '../../lib/devTools'; import ButtonPrimary from '../Buttons/ButtonPrimary'; import CreateAccountModal from '../CreateAccountModal/CreateAccountModal'; import LoginModal from '../LoginModal/LoginModal'; +import { userName } from '../../stores/profile'; +import { PrimalUser } from '../../types/primal'; -const HomeHeader: Component< { id?: string} > = (props) => { +const HomeHeader: Component< { + id?: string, + hasNewPosts: () => boolean, + loadNewContent: () => void, + newPostCount: () => number, + newPostAuthors: PrimalUser[], +} > = (props) => { const account = useAccountContext(); const home = useHomeContext(); const settings = useSettingsContext(); const intl = useIntl(); + let smallHeader: HTMLDivElement | undefined; + let lastScrollTop = document.body.scrollTop || document.documentElement.scrollTop; const onScroll = () => { const scrollTop = document.body.scrollTop || document.documentElement.scrollTop; - const smallHeader = document.getElementById('small_header'); + // const smallHeader = document.getElementById('small_header'); const border = document.getElementById('small_bottom_border'); home?.actions.updateScrollTop(scrollTop); @@ -33,16 +43,17 @@ const HomeHeader: Component< { id?: string} > = (props) => { const isScrollingDown = scrollTop > lastScrollTop; lastScrollTop = scrollTop; - if (scrollTop < 117) { + if (scrollTop < 2) { if (border) { border.style.display = 'none'; } + smallHeader?.classList.add(styles.instaHide); smallHeader?.classList.remove(styles.hiddenSelector); smallHeader?.classList.remove(styles.fixedSelector); return; } - if (lastScrollTop < 117) { + if (lastScrollTop < 2) { smallHeader?.classList.add(styles.instaHide); return; } @@ -96,18 +107,41 @@ const HomeHeader: Component< { id?: string} > = (props) => { +
+ 0 && home?.selectedFeed} + > + + -
+ + + +
+ +
= (props) => {
+ + + +
+ +
+
); diff --git a/src/components/HomeHeaderPhone/HomeHeaderPhone.module.scss b/src/components/HomeHeaderPhone/HomeHeaderPhone.module.scss index ed87ab3..25f4643 100644 --- a/src/components/HomeHeaderPhone/HomeHeaderPhone.module.scss +++ b/src/components/HomeHeaderPhone/HomeHeaderPhone.module.scss @@ -1,6 +1,6 @@ .fullHeader { display: grid; - width: 100%; + width: 100vw; grid-template-columns: 1fr; grid-template-rows: 48px 4px; grid-template-areas: "phone_header" "phone_border"; diff --git a/src/components/HomeSidebar/HomeSidebar.module.scss b/src/components/HomeSidebar/HomeSidebar.module.scss index c4c8346..6c32fe3 100644 --- a/src/components/HomeSidebar/HomeSidebar.module.scss +++ b/src/components/HomeSidebar/HomeSidebar.module.scss @@ -4,8 +4,7 @@ top: 0px; width: 100%; height: 44px; - // background-color: var(--background-site); - background: var(--fade-gradient-vertical); + background-color: var(--background-site); z-index: 5; padding-bottom: 22px; display:flex; diff --git a/src/components/HomeSidebar/HomeSidebar.tsx b/src/components/HomeSidebar/HomeSidebar.tsx index 6cba5bb..cba9345 100644 --- a/src/components/HomeSidebar/HomeSidebar.tsx +++ b/src/components/HomeSidebar/HomeSidebar.tsx @@ -1,15 +1,16 @@ -import { Component, createEffect, createSignal, For, onCleanup } from 'solid-js'; +import { Component, createEffect, createSignal, For, onCleanup, onMount, Show } from 'solid-js'; import { createStore } from 'solid-js/store'; import { APP_ID } from '../../App'; import { getMostZapped4h, getTrending24h } from '../../lib/feed'; import { humanizeNumber } from '../../lib/stats'; -import { convertToNotes, sortingPlan } from '../../stores/note'; +import { convertToNotes, sortByRecency, sortingPlan } from '../../stores/note'; import { Kind } from '../../constants'; import { isConnected, refreshSocketListeners, removeSocketListeners, - socket + socket, + subscribeTo } from '../../sockets'; import { FeedPage, @@ -17,7 +18,13 @@ import { NostrEvent, NostrEventContent, NostrMentionContent, - PrimalNote + NostrNoteActionsContent, + NostrNoteContent, + NostrStatsContent, + NostrUserContent, + NoteActions, + PrimalNote, + SelectionOption } from '../../types/primal'; import styles from './HomeSidebar.module.scss'; @@ -28,174 +35,211 @@ import { hourNarrow } from '../../formats'; import { home as t } from '../../translations'; import { useAccountContext } from '../../contexts/AccountContext'; import { hookForDev } from '../../lib/devTools'; +import SelectionBox from '../SelectionBox/SelectionBox'; +import { getScoredUsers, searchContent } from '../../lib/search'; +import { store } from '../../services/StoreService'; +import Loader from '../Loader/Loader'; +import { readHomeSidebarSelection, saveHomeSidebarSelection } from '../../lib/localStore'; -const [init, setInit] = createSignal(false); +const sidebarOptions = [ + { + label: 'Trending 24h', + value: 'trending_24h', + }, + { + label: 'Trending 12h', + value: 'trending_12h', + }, + { + label: 'Trending 4h', + value: 'trending_4h', + }, + { + label: 'Trending 1h', + value: 'trending_1h', + }, + { + label: '', + value: '', + disabled: true, + separator: true, + }, -const [data, setData] = createStore>({ - trending: { - messages: [], - users: {}, - postStats: {}, - notes: [], - mentions: {}, + { + label: 'Most-zapped 24h', + value: 'mostzapped_24h', }, - mostzapped: { - messages: [], - users: {}, - postStats: {}, - notes: [], - mentions: {}, + { + label: 'Most-zapped 12h', + value: 'mostzapped_12h', }, -}); + { + label: 'Most-zapped 4h', + value: 'mostzapped_4h', + }, + { + label: 'Most-zapped 1h', + value: 'mostzapped_1h', + }, +]; const HomeSidebar: Component< { id?: string } > = (props) => { const intl = useIntl(); const account = useAccountContext(); - onCleanup(() => { - removeSocketListeners( - socket(), - { message: onMessage, close: onSocketClose }, - ); + const [searchResults, setSearchResults] = createStore<{ notes: PrimalNote[], page: FeedPage, isFetching: boolean, query: SelectionOption | undefined }>({ + notes: [], + page: { + messages: [], + users: {}, + postStats: {}, + mentions: {}, + noteActions: {}, + }, + isFetching: false, + query: undefined, }); + const saveNotes = (newNotes: PrimalNote[]) => { + setSearchResults('notes', () => [ ...newNotes.slice(0, 24) ]); + setSearchResults('isFetching', () => false); + }; - createEffect(() => { - if (isConnected() && !init()) { - refreshSocketListeners( - socket(), - { message: onMessage, close: onSocketClose }, + const updatePage = (content: NostrEventContent) => { + if (content.kind === Kind.Metadata) { + const user = content as NostrUserContent; + + setSearchResults('page', 'users', + (usrs) => ({ ...usrs, [user.pubkey]: { ...user } }) ); - - setData(() => ({ - trending: { - messages: [], - users: {}, - postStats: {}, - notes: [], - mentions: {}, - }, - mostzapped: { - messages: [], - users: {}, - postStats: {}, - notes: [], - mentions: {}, - }, - })); - - if (account?.isKeyLookupDone) { - getTrending24h(account?.publicKey, `sidebar_trending_${APP_ID}`); - getMostZapped4h(account?.publicKey, `sidebar_zapped_${APP_ID}`); - } - } - }); - - const processNotes = (type: string, key: string, content: NostrEventContent | undefined) => { - - const sort = sortingPlan(key); - - if (type === 'EOSE') { - const newPosts = sort(convertToNotes({ - users: data[key].users, - messages: data[key].messages, - postStats: data[key].postStats, - mentions: data[key].mentions, - })); - - setData(key, 'notes', () => [ ...newPosts ]); - - setInit(true); return; } - if (type === 'EVENT') { - if (content && content.kind === Kind.Metadata) { - setData(key, 'users', (users) => ({ ...users, [content.pubkey]: content})) - } - if (content && (content.kind === Kind.Text || content.kind === Kind.Repost)) { - setData(key, 'messages', (msgs) => [ ...msgs, content]); - } - if (content && content.kind === Kind.NoteStats) { - const stat = JSON.parse(content.content); - setData(key, 'postStats', (stats) => ({ ...stats, [stat.event_id]: stat })) - } - if (content && content.kind === Kind.Mentions) { - const mentionContent = content as NostrMentionContent; - const mention = JSON.parse(mentionContent.content); + if ([Kind.Text, Kind.Repost].includes(content.kind)) { + const message = content as NostrNoteContent; - setData(key, 'mentions', - (mentions) => ({ ...mentions, [mention.id]: { ...mention } }) - ); + if (searchResults.page.messages.find(m => m.id === message.id)) { return; } - } - }; -// SOCKET HANDLERS ------------------------------ + setSearchResults('page', 'messages', + (msgs) => [ ...msgs, { ...message }] + ); - const onSocketClose = (closeEvent: CloseEvent) => { - const webSocket = closeEvent.target as WebSocket; - - webSocket.removeEventListener('message', onMessage); - webSocket.removeEventListener('close', onSocketClose); - }; - - const onMessage = (event: MessageEvent) => { - const message: NostrEvent | NostrEOSE = JSON.parse(event.data); - - const [type, subId, content] = message; - - if (subId === `sidebar_trending_${APP_ID}`) { - processNotes(type, 'trending', content); return; } - if (subId === `sidebar_zapped_${APP_ID}`) { - processNotes(type, 'mostzapped', content); + + if (content.kind === Kind.NoteStats) { + const statistic = content as NostrStatsContent; + const stat = JSON.parse(statistic.content); + + setSearchResults('page', 'postStats', + (stats) => ({ ...stats, [stat.event_id]: { ...stat } }) + ); + return; + } + + if (content.kind === Kind.Mentions) { + const mentionContent = content as NostrMentionContent; + const mention = JSON.parse(mentionContent.content); + + setSearchResults('page', 'mentions', + (mentions) => ({ ...mentions, [mention.id]: { ...mention } }) + ); + return; + } + + if (content.kind === Kind.NoteActions) { + const noteActionContent = content as NostrNoteActionsContent; + const noteActions = JSON.parse(noteActionContent.content) as NoteActions; + + setSearchResults('page', 'noteActions', + (actions) => ({ ...actions, [noteActions.event_id]: { ...noteActions } }) + ); return; } }; + const savePage = (page: FeedPage) => { + const newPosts = convertToNotes(page); + + saveNotes(newPosts); + }; + + const doSearch = (query: string) => { + const subid = `home_sidebar_${APP_ID}`; + + const unsub = subscribeTo(subid, (type, _, content) => { + + if (type === 'EOSE') { + savePage(searchResults.page); + unsub(); + return; + } + + if (!content) { + return; + } + + + if (type === 'EVENT') { + updatePage(content); + return; + } + + }); + + setSearchResults('isFetching', () => true); + setSearchResults('notes', () => []); + setSearchResults('page', { messages: [], users: {}, postStats: {}, mentions: {}, noteActions: {} }); + + getScoredUsers(account?.publicKey, query, 10, subid); + } + + createEffect(() => { + const query = searchResults.query?.value; + query && doSearch(query); + }); + + createEffect(() => { + if (account?.isKeyLookupDone) { + const stored = readHomeSidebarSelection(account.publicKey); + + if (stored) { + setSearchResults('query', () => ({...stored})); + return; + } + setSearchResults('query', () => ({ ...sidebarOptions[0]})); + } + }); + return (
+
-
-
- {intl.formatMessage(t.trending)} - - {intl.formatNumber(24, hourNarrow)} - -
+ { + setSearchResults('query', () => ({...option})); + saveHomeSidebarSelection(account?.publicKey, option) + }} + />
- - {(note) => } - - -
-
-
- {intl.formatMessage(t.mostZapped)} - - {intl.formatNumber(4, hourNarrow)} - -
-
- - { - (note) => - - {intl.formatMessage(t.zapPostfix, - { - zaps: humanizeNumber(note.post.zaps, true), - sats: humanizeNumber(note.post.satszapped, true), - })} - + } - + > + + {(note) => } + +
+ +
); } diff --git a/src/components/Layout/Layout.module.scss b/src/components/Layout/Layout.module.scss index e73ef8c..21be60e 100644 --- a/src/components/Layout/Layout.module.scss +++ b/src/components/Layout/Layout.module.scss @@ -1,35 +1,33 @@ .container { - width: 1240px; - // height: 100vh; + width: var(--full-site-w); margin: 0px auto; display: grid; - grid-template-columns: 176px 640px 300px; - grid-column-gap: 32px; + grid-template-columns: var(--left-col-w) var(--center-col-w) var(--right-col-w); } .leftColumn { - >div { position: fixed; - width: 176px; + width: var(--left-col-w); display: grid; - grid-template-rows: 128px 1fr 82px; + grid-template-rows: var(--header-height) 1fr 82px; height: 100%; } .leftHeader { - height: 128px; + height: var(--header-height); display: grid; align-items: center; - justify-content: right; + justify-content: flex-start; } .leftContent { position: relative; display: grid; height: 100%; - justify-content: right; + padding-top: 30px; + justify-content: left; .overlay { position: absolute; @@ -46,28 +44,28 @@ .leftFooter { height: 82px; display: flex; - justify-content: flex-end; + justify-content: flex-start; } } .centerColumn { - display: grid; - grid-template-rows: 128px 1fr; position: relative; + border-inline: 1px solid var(--devider); + min-height: 100vh; } .centerHeader { - width: 640px; + width: 600px; } .centerContent { - width: 640px; + width: 600px; .headerFloater { position: fixed; opacity: 0; pointer-events: none; - width: 640px; + width: 600px; z-index: var(--z-index-floater); &.animatedShow { @@ -80,23 +78,39 @@ .rightColumn { display: grid; - width: 300px; - grid-template-rows: 128px 1fr; + width: var(--right-col-w); + grid-template-rows: var(--header-height) 1fr; grid-row-gap: 28px; } .rightHeader { - height: 128px; + width: var(--right-col-w); + height: var(--header-height); display: grid; align-items: center; justify-content: left; position: fixed; // background-color: var(--background-site); z-index: var(--z-index-header); + + >div { + display: flex; + justify-content: center; + align-items: center; + height: var(--header-height); + width: var(--right-col-w); + + >div { + height: 52px; + } + } } .rightContent { - margin-top: 128px; + margin-top: 112px; + >div { + margin-left: 24px; + } } .modal { @@ -115,7 +129,7 @@ @media only screen and (max-width: 1300px) { .container { width: 1032px; - grid-template-columns: 48px 640px 300px; + grid-template-columns: 48px 600px 332px; } .leftColumn { @@ -123,6 +137,16 @@ position: fixed; width: 48px; } + + .leftHeader { + display: flex; + justify-content: flex-start; + } + + + .leftFooter { + justify-content: flex-start; + } } .rightColumn { @@ -133,7 +157,7 @@ @media only screen and (max-width: 1087px) { .container { width: 720px; - grid-template-columns: 48px 640px; + grid-template-columns: 48px 600px; } .rightColumn { @@ -145,7 +169,7 @@ .container { width: 100%; // height: 100vh; - grid-template-columns: 1fr; + grid-template-columns: 98%; grid-template-rows: 1fr 48px; grid-template-areas: "content" "footer"; } diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 0a8257c..8a851af 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -15,7 +15,6 @@ import { useProfileContext } from '../../contexts/ProfileContext'; import Branding from '../Branding/Branding'; export const [isHome, setIsHome] = createSignal(false); -export const [showNav, setShowNav] = createSignal(false); const Layout: Component = () => { @@ -31,15 +30,17 @@ const Layout: Component = () => { const newNote = document.getElementById('new_note_input'); const newNoteTextArea = document.getElementById('new_note_text_area') as HTMLTextAreaElement; - if (!newNote || !newNoteTextArea) { - return; - } - if (account?.showNewNoteForm) { + if (!newNote || !newNoteTextArea) { + return; + } newNote?.classList.add(styles.animatedShow); newNoteTextArea?.focus(); } else { + if (!newNote || !newNoteTextArea) { + return; + } newNote?.classList.remove(styles.animatedShow); newNoteTextArea.value = ''; } @@ -51,7 +52,6 @@ const Layout: Component = () => { onMount(() => { window.addEventListener('resize', onResize); - console.log('OVERLAY: ', location) }); onCleanup(() => { @@ -100,7 +100,7 @@ const Layout: Component = () => {
- +
@@ -120,15 +120,17 @@ const Layout: Component = () => {
-
-
- -
+ +
+
+ +
-
- +
+ +
-
+
diff --git a/src/components/LinkPreview/LinkPreview.module.scss b/src/components/LinkPreview/LinkPreview.module.scss index 7ce6dc9..a66c745 100644 --- a/src/components/LinkPreview/LinkPreview.module.scss +++ b/src/components/LinkPreview/LinkPreview.module.scss @@ -1,11 +1,19 @@ .linkPreview { width: 100%; text-decoration: none; - color: var(--text-tertiary-2); + color: var(--text-tertiary); font-size: 16px; font-weight: 400; line-height: 22px; text-align: left; + display: block; + overflow: hidden; + border-radius: var(--border-radius-small); + background-color: var(--background-input); + + &:hover { + text-decoration: none !important; + } } .previewInfo { diff --git a/src/components/LinkPreview/LinkPreview.tsx b/src/components/LinkPreview/LinkPreview.tsx index 248ccb2..5f03080 100644 --- a/src/components/LinkPreview/LinkPreview.tsx +++ b/src/components/LinkPreview/LinkPreview.tsx @@ -1,21 +1,55 @@ -import { Component, Show } from 'solid-js'; +import { Component, createMemo, Show } from 'solid-js'; +import { useMediaContext } from '../../contexts/MediaContext'; import { hookForDev } from '../../lib/devTools'; import styles from './LinkPreview.module.scss'; const LinkPreview: Component<{ preview: any, id?: string }> = (props) => { + const media = useMediaContext(); + const encodedUrl = encodeURI(new URL(props.preview.url).origin); + const image = () => { + const i = media?.actions.getMedia(props.preview.images[0] || '', 'm'); + + return i; + }; + + const height = () => { + const img = image(); + + if (!img) { + return '100%'; + } + + const mediaHeight = img.h; + const mediaWidth = img.w || 0; + const imgWidth = 524; + + const ratio = mediaWidth / imgWidth; + + const h = ratio > 1 ? + mediaHeight / ratio : + mediaHeight * ratio; + + return `${h}px`; + }; + return ( - -
- + +
+
diff --git a/src/components/Loader/Loader.module.scss b/src/components/Loader/Loader.module.scss index e0a9d54..0fd6d2b 100644 --- a/src/components/Loader/Loader.module.scss +++ b/src/components/Loader/Loader.module.scss @@ -22,7 +22,7 @@ margin: auto; height: 32px; width: 32px; - border: 2px solid var(--brand-1); + border: 2px solid var(--accent); border-radius: 50%; opacity: 0; -webkit-animation: loader-1 1.5s cubic-bezier(0.075, 0.820, 0.165, 1.000) infinite; diff --git a/src/components/LoginModal/LoginModal.module.scss b/src/components/LoginModal/LoginModal.module.scss index 4c08a8d..59363fc 100644 --- a/src/components/LoginModal/LoginModal.module.scss +++ b/src/components/LoginModal/LoginModal.module.scss @@ -1,17 +1,13 @@ .modal { position: fixed; - width: 420px; + width: 440px; color: var(--text-secondary); - background-color: var(--background-site); - background: linear-gradient(var(--background-site), - var(--background-site)) padding-box, - var(--brand-gradient) border-box; - border: 1px solid transparent; - border-radius: 6px; + background-color: var(--background-input); + border-radius: 8px; display: flex; flex-direction: column; - padding: 22px; + padding: 24px; .xClose { background: none; @@ -46,17 +42,16 @@ } .title { - font-weight: 800; font-size: 18px; - line-height: 18px; - color: var(--text-secondary); - text-transform: uppercase; + font-weight: 600; + line-height: 20px; + color: var(--text-primary); margin-bottom: 20px; } .description { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; line-height: 20px; margin-bottom: 28px; @@ -74,17 +69,18 @@ button { width: fit-content; - min-width: 192px; - padding: 10px; + padding-block: 10px; + padding-inline: 44px; margin: 0px; } } .alternative { - color: var(--text-secondary); - font-size: 14px; + color: var(--text-primary); + font-size: 15px; + font-style: normal; font-weight: 400; - line-height: 24px; + line-height: 20px; } } diff --git a/src/components/MissingPage/MissingPage.module.scss b/src/components/MissingPage/MissingPage.module.scss index 74d8360..94c76b7 100644 --- a/src/components/MissingPage/MissingPage.module.scss +++ b/src/components/MissingPage/MissingPage.module.scss @@ -1,21 +1,26 @@ .fullHeader { display: grid; - height: 120px; + height: 84px; align-items: center; justify-content: left; + padding-inline: 20px; + + border-bottom: 1px solid var(--devider); >div { - font-weight: 300; font-size: 32px; + font-weight: 400; line-height: 34px; - color: var(--brand-text); + color: var(--text-secondary); text-transform: lowercase; } } .comingSoon { - font-weight: 300; + font-weight: 400; font-size: 18px; line-height: 34px; + padding-inline: 20px; + margin-top: 24px; color: var(--text-secondary); } diff --git a/src/components/NavHeader/NavHeader.module.scss b/src/components/NavHeader/NavHeader.module.scss new file mode 100644 index 0000000..2277b0c --- /dev/null +++ b/src/components/NavHeader/NavHeader.module.scss @@ -0,0 +1,53 @@ +.navHeader { + position: fixed; + display: flex; + justify-content: flex-start; + align-items: flex-start; + height: 72px; + width: calc(var(--central-content-width) - 2px); + margin: 0; + padding: 0; + padding-top: 32px; + background-color: var(--background-modal); + z-index: var(--z-index-header); + backdrop-filter: blur(10px); + + font-size: 16px; + font-weight: 600; + line-height: 16px; + color: var(--text-secondary); + + border: none; + border-bottom: 1px solid var(--devider); + border-radius: 0; + + outline: none; + box-shadow: none; + + &:focus { + outline: none; + box-shadow: none; + } + +} + +.title { + height: 16px; + padding-top: 1px; +} + +.backIcon { + display: inline-block; + border: none; + box-shadow: none; + background-color: unset; + margin: 0px; + padding: 0px; + width: 16px; + height: 16px; + margin-left: 20px; + margin-right: 12px; + background-color: var(--text-secondary); + -webkit-mask: url(../../assets/icons/back.svg) no-repeat center; + mask: url(../../assets/icons/back.svg) no-repeat center; +} diff --git a/src/components/NavHeader/NavHeader.tsx b/src/components/NavHeader/NavHeader.tsx new file mode 100644 index 0000000..c9717f1 --- /dev/null +++ b/src/components/NavHeader/NavHeader.tsx @@ -0,0 +1,19 @@ +import { Component} from 'solid-js'; +import { hookForDev } from '../../lib/devTools'; + +import styles from './NavHeader.module.scss'; + +const NavHeader: Component<{ + title: string, +}> = (props) => { + return ( + + ); +} + +export default hookForDev(NavHeader); diff --git a/src/components/NavLink/NavLink.module.scss b/src/components/NavLink/NavLink.module.scss index 6139847..ee76595 100644 --- a/src/components/NavLink/NavLink.module.scss +++ b/src/components/NavLink/NavLink.module.scss @@ -1,20 +1,31 @@ @mixin iconNav { - width: 32px; - height: 32px; + width: 24px; + height: 24px; background-color: var(--text-secondary); } .navLink { position: relative; - text-align: right; - margin: 0px 0px 28px 0px; + margin: 0px 0px 36px 0px; padding: 0px; background: none; border: none; border-radius: 0px; + display: flex; + justify-content: flex-start; - div { - display: inline; + a { + .label { + margin-left: 16px; + font-size: 18px; + font-weight: 600; + line-height: 20px; + display: flex; + } + + &:focus { + background: none; + } } p { @@ -34,8 +45,8 @@ .exploreIcon { @include iconNav; - -webkit-mask: url(../../assets/icons/explore.svg) no-repeat center; - mask: url(../../assets/icons/explore.svg) no-repeat center; + -webkit-mask: url(../../assets/icons/search.svg) no-repeat center; + mask: url(../../assets/icons/search.svg) no-repeat center; } .messagesIcon { @include iconNav; @@ -64,91 +75,103 @@ } .active { - p { - color: var(--active-link); - text-decoration: underline; - } - div { - background-color: var(--active-link); + display: flex; + justify-content: flex-start; + align-items: flex-end; + background: none; + + >div { + background-color: var(--text-primary); } - .homeIcon { - background-color: var(--text-primary); - } - .exploreIcon { - background-color: var(--text-primary); - } - .messagesIcon { - background-color: var(--text-primary); - } - .notificationsIcon { - background-color: var(--text-primary); - } - .downloadIcon { - background-color: var(--text-primary); - } - .settingsIcon { - background-color: var(--text-primary); - } - .helpIcon { - background-color: var(--text-primary); + .label { + color: var(--text-primary); + background: none; } } .inactive { - p { - color: var(--inactive-link); + display: flex; + justify-content: flex-start; + align-items: flex-end; + + >div { + background-color: var(--text-secondary); } - div { - background-color: var(--inactive-link); + + .label { + color: var(--text-secondary); + background: none; + } +} + +.bubble { + display: flex; + justify-content: center; + align-items: center; + width: 18px; + height: 18px; + + margin-left: 2px; + + font-family: 'Roboto Condensed'; + font-weight: 500; + font-size: 12px; + line-height: 11px; + + background: var(--accent); + border: 1px solid var(--background-site); + border-radius: 9px; + + color: var(--text-primary-button); + + &.doubleSize { + width: 24px; + } + + &.tripleSize { + width: 26px; + padding-left: 2px; } } @media only screen and (max-width: 1300px) { .navLink { - margin-bottom: 22px; + a { + .label { + display: none; + } + } + } - width: fit-content; - div { - display: inline-block; + .bubble { + width: 8px; + height: 8px; + >div { + display: none; } - p { - display: none; + &.doubleSize { + width: 8px; + height: 8px; + } + + &.tripleSize { + width: 8px; + height: 8px; } } } @media only screen and (max-width: 720px) { + .navLink { + a { + .label { + display: none; + } + } + } .hiddenOnSmallScreens { display: none } } - -.bubble { - position: absolute; - text-align: center; - padding-top: 2px; - padding-inline: 4px; - top: 0; - right: -18px; - min-width: 18px; - min-height: 18px; - border-radius: 8px; - font-weight: 500; - font-size: 12px; - line-height: 12px; - - background: var(--brand-gradient); - border: 1px solid var(--background-site); - - color: white; - text-shadow: 0.5px 0.5px 0px black; - - &.doubleSize { - right: -24px; - } - &.tripleSize { - right: -30px; - } -} diff --git a/src/components/NavLink/NavLink.tsx b/src/components/NavLink/NavLink.tsx index 7e7ccac..df93391 100644 --- a/src/components/NavLink/NavLink.tsx +++ b/src/components/NavLink/NavLink.tsx @@ -12,21 +12,15 @@ const NavLink: Component<{ bubble?: () => number, hiddenOnSmallScreens?: boolean, }> = (props) => { - - const navigate = useNavigate(); const location = useLocation(); - const shouldScroll = () => props.to === location.pathname; - - const onClick = (e: Event) => { - if (shouldScroll()) { + const scrollIfInactive = (e: Event) => { + if (props.to === location.pathname) { e.preventDefault(); window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); return; } - - navigate('/home'); } const bubbleClass = () => { @@ -42,17 +36,22 @@ const NavLink: Component<{ } return ( -
+
) } diff --git a/src/components/NavMenu/NavMenu.module.scss b/src/components/NavMenu/NavMenu.module.scss index 1e73811..03d7afe 100644 --- a/src/components/NavMenu/NavMenu.module.scss +++ b/src/components/NavMenu/NavMenu.module.scss @@ -1,38 +1,41 @@ .sideNav { display: flex; flex-direction: column; - - > div { - margin-bottom: 28px; - } + margin-left: 8px; } .callToAction { - display: grid; - justify-content: right; - margin-top: 15px; + margin-left: 8px; + width: 156px; + display: flex; + flex-direction: column; + align-items: center; + + >button { + margin: 0; + width: 100% ; + } .message { color: var(--text-tertiary); text-align: right; font-size: 15px; + font-style: normal; font-weight: 400; line-height: 16px; - margin-bottom: 4px; - } - - .action { - button { - margin: 0; - } + margin-bottom: 8px; } } @media only screen and (max-width: 1300px) { - .callToAction { - .message, .action { - display: none; + margin-left: 2px; + width: 36px; + height: 36px; + + >button { + padding: 0; + margin: 0; } } } @@ -65,3 +68,15 @@ } } } + + +.postIcon { + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + + background-color: var(--text-primary-button); + -webkit-mask: url(../../assets/icons/post.svg) no-repeat 0 0 / 18px 18px; + mask: url(../../assets/icons/post.svg) no-repeat 0 0 / 18px 18px; +} diff --git a/src/components/NavMenu/NavMenu.tsx b/src/components/NavMenu/NavMenu.tsx index 5cd90df..3aacf4c 100644 --- a/src/components/NavMenu/NavMenu.tsx +++ b/src/components/NavMenu/NavMenu.tsx @@ -11,6 +11,7 @@ import FloatingNewPostButton from '../FloatingNewPostButton/FloatingNewPostButto import styles from './NavMenu.module.scss'; import { hookForDev } from '../../lib/devTools'; import ButtonPrimary from '../Buttons/ButtonPrimary'; +import { useMediaContext } from '../../contexts/MediaContext'; const NavMenu: Component< { id?: string } > = (props) => { const account = useAccountContext(); @@ -18,6 +19,7 @@ const NavMenu: Component< { id?: string } > = (props) => { const messages = useMessagesContext(); const intl = useIntl(); const loc = useLocation(); + const media = useMediaContext(); const links = [ { @@ -64,6 +66,8 @@ const NavMenu: Component< { id?: string } > = (props) => { }, ]; + const isBigScreen = () => (media?.windowSize.w || 0) > 1300; + return (
- + +
+ + } + > + + {intl.formatMessage(tActions.newNote)} + +
- +
{intl.formatMessage(tPlaceholders.welcomeMessage)}
-
- - {intl.formatMessage(tActions.getStarted)} - -
+ + {intl.formatMessage(tActions.getStarted)} +
diff --git a/src/components/NewNote/EditBox/EditBox.module.scss b/src/components/NewNote/EditBox/EditBox.module.scss index e4eba4d..c3237f5 100644 --- a/src/components/NewNote/EditBox/EditBox.module.scss +++ b/src/components/NewNote/EditBox/EditBox.module.scss @@ -39,8 +39,8 @@ width: 100%; height: 100%; padding: 1px; - background: var(--brand-gradient); border-radius: 6px; + border: 1px solid var(--accent); display: block; position: relative; } @@ -52,8 +52,6 @@ font-size: 18px; line-height: 20px; margin: 0px; - border-radius: 6px; - border: none; color: var(--text-tertiary); background-color: var(--background-site); padding-bottom: 11px; @@ -74,18 +72,14 @@ align-items: center; justify-content: flex-end; width: calc(100% - 16px); - // border: solid 1px red; padding-top: 8px; background-color: var(--background-site); >button { - width: 80px; - height: 28px; - min-width: 80px; - margin: 0px 0px 11px 8px; + min-width: 110px; + margin-left: 8px; } .editorOptions { width: 100%; - // padding-left: 80px; .attachIcon { width: 26px; @@ -144,10 +138,9 @@ .searchSuggestions { width: 300px; - background-color: var(--background-site); - border: 1px solid var(--text-tertiary-2); - // box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.8); - border-radius: 4px; + background-color: var(--background-input); + border: none; + border-radius: 8px; position: absolute; top: 0px; @@ -185,6 +178,7 @@ textarea { &:focus { border: none; outline: none; + box-shadow: none; } } @@ -238,7 +232,7 @@ textarea::-webkit-scrollbar{ color: var(--text-primary); margin: 0px 14px 32px 0px; padding: 0px; - background-color: var(--background-card); + background-color: var(--background-sheet); border-radius: 4px; padding: 12px; } @@ -252,9 +246,8 @@ textarea::-webkit-scrollbar{ max-height: 200px; overflow-y: scroll; padding: 4px; - background-color: var(--background-site); - border: 1px solid var(--text-tertiary-2); - // box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.8); + background-color: var(--background-input); + border: none; border-radius: 8px; top: 0px; diff --git a/src/components/NewNote/EditBox/EditBox.tsx b/src/components/NewNote/EditBox/EditBox.tsx index d6590fc..b5472c3 100644 --- a/src/components/NewNote/EditBox/EditBox.tsx +++ b/src/components/NewNote/EditBox/EditBox.tsx @@ -36,6 +36,8 @@ import { } from "../../../translations"; import { useMediaContext } from "../../../contexts/MediaContext"; import { hookForDev } from "../../../lib/devTools"; +import ButtonPrimary from "../../Buttons/ButtonPrimary"; +import ButtonSecondary from "../../Buttons/ButtonSecondary"; type AutoSizedTextArea = HTMLTextAreaElement & { _baseScrollHeight: number }; @@ -1212,22 +1214,15 @@ const EditBox: Component<{
- - + {intl.formatMessage(tActions.notePostNew)} + + + {intl.formatMessage(tActions.cancel)} +
) diff --git a/src/components/NewNote/NewNote.module.scss b/src/components/NewNote/NewNote.module.scss index 57a2ed5..dfe12fa 100644 --- a/src/components/NewNote/NewNote.module.scss +++ b/src/components/NewNote/NewNote.module.scss @@ -34,7 +34,7 @@ width: 100%; height: 100%; padding: 1px; - background: var(--brand-gradient); + background: none; border-radius: 6px; display: block; position: relative; @@ -48,7 +48,7 @@ line-height: 20px; margin: 0px; border-radius: 6px; - border: none; + border: 2px solid var(--accent); color: var(--text-tertiary); background-color: var(--background-site); padding-bottom: 11px; diff --git a/src/components/NostrStats/NostrStats.module.scss b/src/components/NostrStats/NostrStats.module.scss index d0d93e2..bc1a106 100644 --- a/src/components/NostrStats/NostrStats.module.scss +++ b/src/components/NostrStats/NostrStats.module.scss @@ -16,16 +16,16 @@ .netstat { .number { - font-size: 24px; + font-size: 22px; + font-weight: 400; line-height: 28px; - font-weight: 300; color: var(--text-primary); } .label { - font-size: 16px; + font-size: 15px; + font-weight: 400; line-height: 20px; - font-weight: 300; color: var(--text-tertiary); text-transform: lowercase; } diff --git a/src/components/Note/Note.module.scss b/src/components/Note/Note.module.scss index 4d801ae..6a7d6f4 100644 --- a/src/components/Note/Note.module.scss +++ b/src/components/Note/Note.module.scss @@ -1,83 +1,154 @@ -.post { - background-color: var(--background-card); +.note { display: flex; flex-direction: column; - // grid-template-columns: 60px 1fr; - // grid-template-rows: 1fr; - // grid-template-areas: "avatar content"; - padding: 0px; - border-radius: 8px; - // pointer-events: none; + padding: 12px; + margin: 0px; + + text-decoration: none; + color: unset; + background-color: var(--background-site); + border: none; + border-bottom: 1px solid var(--devider); + border-radius: 0; + + width: calc(100% - 2px); + + &.parent { + border: none; + } + + .header { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + + .repostedBy { + padding-bottom: 16px; + display: flex; + >span { + >a { + margin-inline: 5px; + color: var(--text-tertiary); + text-decoration: none; + } + color: var(--text-tertiary); + font-size: 14px; + line-height: 14px; + font-weight: 400; + >span { + text-transform: lowercase; + } + } + } + } .content { - grid-area: content; - display: flex; - flex-direction: column; - margin-top: 21px; - margin-left: 60px; - // grid-template-columns: 1fr; - // grid-template-rows: 48px 1fr 28px; - // grid-row-gap: 16px; - // grid-template-areas: "header" "message" "footer"; + display: grid; + grid-template-columns: 50px 1fr; + .leftSide { + width: 42px; + margin-right: 8px; - .message { - position: relative; - grid-area: message; - color: var(--text-primary); - word-break: break-word; - font-size: 16px; - line-height: 24px; - width: 100%; - // max-height: 650px; - // overflow: hidden; - margin-bottom: 17px; + .ancestorLine { + border-left: 1px solid var(--devider); + height: calc(100% - 12px); + margin-left: 21px; + } + } - a:hover { - text-decoration: underline; + .rightSide { + display: flex; + flex-direction: column; + + .message { + color: var(--text-primary); + word-break: break-word; + font-size: 15px; + font-weight: 400px; + line-height: 20px; + margin-top: 4px; + margin-bottom: 16px; } - .messageFade { - position: absolute; - z-index: 1; - top: 610px; - left: 0; - pointer-events: none; - background-image: var(--fade-note-vertical); - width: 100%; - height: 40px; - } + .replyingTo { + font-size: 15px; + font-weight: 400; + line-height: 20px; + margin-top: 6px; + .label { + color: var(--text-primary); + } + .author { + color: var(--accent); + text-decoration: none; + &:hover { + text-decoration: underline; + } + } + } } } } +.authorInfo { + display: flex; + justify-content: flex-start; + overflow: hidden; + align-items: center; + justify-content: flex-start; + width: 524px; + position: relative; + .userName { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + max-width: 226px; + color: var(--text-primary); -.postLink { - text-decoration: none; - color: unset; - margin: 0px; - padding: 16px 20px; - // background: var(--brand-gradient-vertical); - background-color: var(--background-card); - border-radius: 8px; - display: block; - transition: 0.2s padding; - margin-top: 8px; - >div { - border-radius: 4px; - transition: 0.2s border-radius ease-out; + font-size: 14px; + font-weight: 700; + line-height: 14px; } + .time{ + display: flex; + margin-left: 2px; + min-width: fit-content; + font-size: 14px; + font-weight: 400; + line-height: 14px; + color: var(--text-tertiary); - // &:hover { - // padding-left: 4px; - // transition: 0.2s padding; - // border-radius: 4px; - // >div { - // border-radius: 0px 4px 4px 0px; - // transition: 0.2s border-radius ease-out; - // } - // } + .ellipsisIcon { + width: 11px; + height: 14px; + background-color: var(--text-tertiary); + -webkit-mask: url(../../assets/icons/ellipsis.svg) no-repeat center; + mask: url(../../assets/icons/ellipsis.svg) no-repeat center; + } + } + .verification { + max-width: 216px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + color: var(--text-tertiary); + + font-size: 14px; + font-weight: 400; + line-height: 14px; + } +} + +.repostIcon { + width: 16px; + height: 16px; + background-color: var(--text-tertiary); + -webkit-mask: url(../../assets/icons/feed_repost.svg) no-repeat 0 / 100%; + mask: url(../../assets/icons/feed_repost.svg) no-repeat 0 / 100%; } .repostedBy { @@ -86,10 +157,12 @@ >span { >a { margin-inline: 5px; + color: var(--text-tertiary); + text-decoration: none; } color: var(--text-tertiary); - font-size: 16px; - line-height: 16px; + font-size: 14px; + line-height: 14px; font-weight: 400; >span { text-transform: lowercase; @@ -97,21 +170,61 @@ } } +.contextMenu { + position: relative; + width: 16px; + height: 32px; + display: flex; + align-items: center; + text-align: center; + font-weight: bold; -@media only screen and (max-width: 720px) { - .postLink { - width: 100vw; - .post { - width: 100%; - // grid-template-columns: 62px 1fr; - margin-left: 0px; - margin-right: 0px; - padding-right: 0px; - .content { - margin-left: 0; - } + .contextButton { + width: 16px; + height: 32px; + padding: 0; + margin: 0; + background: none; + border: none; + outline: none; + display: flex; + justify-content: center; + align-items: flex-start; + + &:focus { + outline: none; + box-shadow: none; } + .contextIcon { + width: 16px; + height: 14px; + background-color: var(--text-secondary-2); + -webkit-mask: url(../../assets/icons/context.svg) no-repeat 0 / 100%; + mask: url(../../assets/icons/context.svg) no-repeat 0 / 100%; + } + + &:hover { + .contextIcon { + background-color: var(--text-primary); + } + } + } +} + +@media only screen and (max-width: 720px) { + .note { + width: 100vw; + + .content { + .rightSide { + width: calc(100% - 2px); + } + } + } + + .authorInfo{ + width: 100%; } } diff --git a/src/components/Note/Note.tsx b/src/components/Note/Note.tsx index e52f3f9..01178c6 100644 --- a/src/components/Note/Note.tsx +++ b/src/components/Note/Note.tsx @@ -1,5 +1,5 @@ import { A } from '@solidjs/router'; -import { Component, createEffect, createSignal, Show } from 'solid-js'; +import { Component, createSignal, Show } from 'solid-js'; import { PrimalNote } from '../../types/primal'; import ParsedNote from '../ParsedNote/ParsedNote'; import NoteFooter from './NoteFooter/NoteFooter'; @@ -8,12 +8,18 @@ import NoteHeader from './NoteHeader/NoteHeader'; import styles from './Note.module.scss'; import { useThreadContext } from '../../contexts/ThreadContext'; import { useIntl } from '@cookbook/solid-intl'; -import { authorName, truncateNpub } from '../../stores/profile'; +import { authorName, userName } from '../../stores/profile'; import { note as t } from '../../translations'; import { hookForDev } from '../../lib/devTools'; import NoteReplyHeader from './NoteHeader/NoteReplyHeader'; +import Avatar from '../Avatar/Avatar'; +import NoteAuthorInfo from './NoteAuthorInfo'; +import NoteRepostHeader from './NoteRepostHeader'; +import PrimalMenu from '../PrimalMenu/PrimalMenu'; +import NoteContextMenu from './NoteContextMenu'; +import NoteReplyToHeader from './NoteReplyToHeader'; -const Note: Component<{ note: PrimalNote, id?: string }> = (props) => { +const Note: Component<{ note: PrimalNote, id?: string, parent?: boolean }> = (props) => { const threadContext = useThreadContext(); const intl = useIntl(); @@ -24,66 +30,45 @@ const Note: Component<{ note: PrimalNote, id?: string }> = (props) => { threadContext?.actions.setPrimaryNote(note); }; - const reposterName = () => { - const r = repost(); - - if (!r) { - return ''; - } - - return authorName(r.user); - } - - const [openCustomZap, setOpenCustomZap] = createSignal(false); - return ( navToThread(props.note)} data-event={props.note.post.id} data-event-bech32={props.note.post.noteId} > - -
-
- -
- {reposterName()} - - - {intl.formatMessage(t.reposted)} - - -
- -
- { - setOpenCustomZap(true); - setTimeout(() => setOpenCustomZap(false), 10); - }} - /> - } - > - { - setOpenCustomZap(true); - setTimeout(() => setOpenCustomZap(false), 10); - }} - /> +
+ + -
+
+
+
+ + + + +
+
+
+ +
+ + + +
- + +
diff --git a/src/components/Note/NoteAuthorInfo.tsx b/src/components/Note/NoteAuthorInfo.tsx new file mode 100644 index 0000000..1c2120e --- /dev/null +++ b/src/components/Note/NoteAuthorInfo.tsx @@ -0,0 +1,59 @@ +import { A } from '@solidjs/router'; +import { Component, createSignal, Show } from 'solid-js'; +import { PrimalNote, PrimalUser } from '../../types/primal'; +import ParsedNote from '../ParsedNote/ParsedNote'; +import NoteFooter from './NoteFooter/NoteFooter'; +import NoteHeader from './NoteHeader/NoteHeader'; + +import styles from './Note.module.scss'; +import { useThreadContext } from '../../contexts/ThreadContext'; +import { useIntl } from '@cookbook/solid-intl'; +import { authorName, nip05Verification, truncateNpub } from '../../stores/profile'; +import { note as t } from '../../translations'; +import { hookForDev } from '../../lib/devTools'; +import NoteReplyHeader from './NoteHeader/NoteReplyHeader'; +import Avatar from '../Avatar/Avatar'; +import { date } from '../../lib/dates'; +import VerificationCheck from '../VerificationCheck/VerificationCheck'; + +const NoteAuthorInfo: Component<{ + author: PrimalUser, + time: number, + id?: string, +}> = (props) => { + + const threadContext = useThreadContext(); + const intl = useIntl(); + + return ( +
+ + + {authorName(props.author)} + + + + + + + {nip05Verification(props.author)} + + + + +
+ {date(props.time).label} +
+
+ ) +} + +export default hookForDev(NoteAuthorInfo); diff --git a/src/components/Note/NoteContextMenu.tsx b/src/components/Note/NoteContextMenu.tsx new file mode 100644 index 0000000..19d53e5 --- /dev/null +++ b/src/components/Note/NoteContextMenu.tsx @@ -0,0 +1,218 @@ +import { A } from '@solidjs/router'; +import { Component, createEffect, createSignal, Show } from 'solid-js'; +import { MenuItem, NostrRelaySignedEvent, PrimalNote, PrimalRepost, PrimalUser } from '../../types/primal'; +import ParsedNote from '../ParsedNote/ParsedNote'; +import NoteFooter from './NoteFooter/NoteFooter'; +import NoteHeader from './NoteHeader/NoteHeader'; + +import styles from './Note.module.scss'; +import { useThreadContext } from '../../contexts/ThreadContext'; +import { useIntl } from '@cookbook/solid-intl'; +import { authorName, nip05Verification, truncateNpub, userName } from '../../stores/profile'; +import { note as t, actions as tActions, toast as tToast } from '../../translations'; +import { hookForDev } from '../../lib/devTools'; +import NoteReplyHeader from './NoteHeader/NoteReplyHeader'; +import Avatar from '../Avatar/Avatar'; +import { date } from '../../lib/dates'; +import VerificationCheck from '../VerificationCheck/VerificationCheck'; +import PrimalMenu from '../PrimalMenu/PrimalMenu'; +import { useAccountContext } from '../../contexts/AccountContext'; +import { APP_ID } from '../../App'; +import { reportUser } from '../../lib/profile'; +import { useToastContext } from '../Toaster/Toaster'; +import { broadcastEvent } from '../../lib/notes'; +import { getScreenCordinates } from '../../utils'; + +const NoteContextMenu: Component<{ + note: PrimalNote, + openCustomZap?: () => void; + id?: string, +}> = (props) => { + const account = useAccountContext(); + const toaster = useToastContext(); + const intl = useIntl(); + + const [showContext, setContext] = createSignal(false); + const [confirmReportUser, setConfirmReportUser] = createSignal(false); + const [confirmMuteUser, setConfirmMuteUser] = createSignal(false); + + const openContextMenu = (e: MouseEvent) => { + e.preventDefault(); + setContext(true); + }; + + const doMuteUser = () => { + account?.actions.addToMuteList(props.note.post.pubkey); + }; + + const doUnmuteUser = () => { + account?.actions.removeFromMuteList(props.note.post.pubkey); + }; + + const doReportUser = () => { + reportUser(props.note.user.pubkey, `report_user_${APP_ID}`, props.note.user); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorReported, { name: userName(props.note.user)})); + }; + + const copyNoteLink = () => { + navigator.clipboard.writeText(`${window.location.origin}/e/${props.note.post.noteId}`); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.notePrimalLinkCoppied)); + }; + + const copyNoteText = () => { + navigator.clipboard.writeText(`${props.note.post.content}`); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.notePrimalTextCoppied)); + }; + + const copyNoteId = () => { + navigator.clipboard.writeText(`${props.note.post.noteId}`); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.noteIdCoppied)); + }; + + const copyRawData = () => { + navigator.clipboard.writeText(`${JSON.stringify(props.note.msg)}`); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.noteRawDataCoppied)); + }; + + const copyUserNpub = () => { + navigator.clipboard.writeText(`${props.note.user.npub}`); + setContext(false); + toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorNpubCoppied)); + }; + + const broadcastNote = async () => { + if (!account) { + return; + } + + const { success } = await broadcastEvent(props.note.msg as NostrRelaySignedEvent, account?.relays, account?.relaySettings); + setContext(false); + + if (success) { + toaster?.sendSuccess(intl.formatMessage(tToast.noteBroadcastSuccess)); + return; + } + toaster?.sendWarning(intl.formatMessage(tToast.noteBroadcastFail)); + }; + + const onClickOutside = (e: MouseEvent) => { + if ( + !document?.getElementById(`note_context_${props.note.post.id}`)?.contains(e.target as Node) + ) { + setContext(false); + } + } + + createEffect(() => { + if (showContext()) { + document.addEventListener('click', onClickOutside); + } + else { + document.removeEventListener('click', onClickOutside); + } + }); + + const isVerifiedByPrimal = () => { + return !!props.note.user.nip05 && + props.note.user.nip05.endsWith('primal.net'); + } + + const noteContextForEveryone: MenuItem[] = [ + { + label: intl.formatMessage(tActions.noteContext.zap), + action: () => { + props.openCustomZap && props.openCustomZap(); + setContext(false); + }, + icon: 'feed_zap', + }, + { + label: intl.formatMessage(tActions.noteContext.copyLink), + action: copyNoteLink, + icon: 'copy_note_link', + }, + { + label: intl.formatMessage(tActions.noteContext.copyText), + action: copyNoteText, + icon: 'copy_note_text', + }, + { + label: intl.formatMessage(tActions.noteContext.copyId), + action: copyNoteId, + icon: 'copy_note_id', + }, + { + label: intl.formatMessage(tActions.noteContext.copyRaw), + action: copyRawData, + icon: 'copy_raw_data', + }, + { + label: intl.formatMessage(tActions.noteContext.breadcast), + action: broadcastNote, + icon: 'broadcast', + }, + { + label: intl.formatMessage(tActions.noteContext.copyPubkey), + action: copyUserNpub, + icon: 'copy_pubkey', + }, + ]; + + const noteContextForOtherPeople: MenuItem[] = [ + { + label: intl.formatMessage(tActions.noteContext.muteAuthor), + action: () => { + setConfirmMuteUser(true); + setContext(false); + }, + icon: 'mute_user', + warning: true, + }, + { + label: intl.formatMessage(tActions.noteContext.reportAuthor), + action: () => { + setConfirmReportUser(true); + setContext(false); + }, + icon: 'report', + warning: true, + }, + ]; + + const noteContext = account?.publicKey !== props.note.post.pubkey ? + [ ...noteContextForEveryone, ...noteContextForOtherPeople] : + noteContextForEveryone; + + let context: HTMLDivElement | undefined; + + const determineOrient = () => { + const coor = getScreenCordinates(context); + const height = 380; + return (coor.y || 0) + height < window.innerHeight + window.scrollY ? 'down' : 'up'; + } + + return ( +
+ +
+ ) +} + +export default hookForDev(NoteContextMenu); diff --git a/src/components/Note/NoteFooter/NoteFooter.module.scss b/src/components/Note/NoteFooter/NoteFooter.module.scss index 6466d40..18f1818 100644 --- a/src/components/Note/NoteFooter/NoteFooter.module.scss +++ b/src/components/Note/NoteFooter/NoteFooter.module.scss @@ -6,30 +6,35 @@ @mixin typeDiv { display: flex; - min-width: 64px; align-items: center; } .footer { - display: flex; + display: grid; + grid-template-columns: 128px 128px 128px 128px; position: relative; + width: 100%; + + .context { + position: absolute; + top: 0; + right: 0; + background: none; + display: flex; + justify-content: flex-end; + align-items: center; + } .stat { - // display: grid; - // grid-template-columns: 18px 1fr; - // grid-template-rows: 1fr; - // grid-column-gap: 5px; font-weight: 400; - font-size: 18px; + font-size: 14px; line-height: 16px; align-items: center; margin: 0px; padding: 0px; - margin-right: 60px; border: none; background-color: unset; - width: auto; - min-width: 64px; + width: fit-content; position: relative; .likeType { @@ -71,10 +76,10 @@ &:hover, &.highlighted { .zapType { .statNumber { - color: #FF9F2F; + color: var(--active-zap); } .icon { - background-color: #FF9F2F; + background-color: var(--active-zap); -webkit-mask: url(../../../assets/icons/feed_zap_fill.svg) no-repeat 0 / 100%; mask: url(../../../assets/icons/feed_zap_fill.svg) no-repeat 0 / 100%; } @@ -82,10 +87,10 @@ .likeType { .statNumber { - color: #BC1870; + color: var(--active-liked); } .icon { - background-color: #BC1870; + background-color: var(--active-liked); -webkit-mask: url(../../../assets/icons/feed_like_fill.svg) no-repeat 0 / 100%; mask: url(../../../assets/icons/feed_like_fill.svg) no-repeat 0 / 100%; } @@ -93,10 +98,10 @@ .replyType { .statNumber { - color: #CCCCCC; + color: var(--active-reply); } .icon { - background-color: #CCCCCC; + background-color: var(--active-reply); -webkit-mask: url(../../../assets/icons/feed_reply_fill.svg) no-repeat 0 / 100%; mask: url(../../../assets/icons/feed_reply_fill.svg) no-repeat 0 / 100%; } @@ -104,10 +109,10 @@ .repostType { .statNumber { - color: #66E205; + color: var(--active-reposted); } .icon { - background-color: #66E205; + background-color: var(--active-reposted); -webkit-mask: url(../../../assets/icons/feed_repost_fill.svg) no-repeat 0 / 100%; mask: url(../../../assets/icons/feed_repost_fill.svg) no-repeat 0 / 100%; } @@ -119,8 +124,8 @@ .statNumber { text-align: left; - color: var(--text-secondary); - margin-left: 7px; + color: var(--text-tertiary-2); + padding-left: 7px; } } } @@ -142,7 +147,7 @@ @media only screen and (max-width: 720px) { .footer { - width: auto; + width: 100%; display: flex; align-items: center; justify-content: space-between; @@ -151,5 +156,10 @@ min-width: 0px; margin-right: 0; } + + .context { + display: none; + } } + } diff --git a/src/components/Note/NoteFooter/NoteFooter.tsx b/src/components/Note/NoteFooter/NoteFooter.tsx index 04f5c89..87cdafb 100644 --- a/src/components/Note/NoteFooter/NoteFooter.tsx +++ b/src/components/Note/NoteFooter/NoteFooter.tsx @@ -18,8 +18,10 @@ import { medZapLimit } from '../../../constants'; import { toast as t } from '../../../translations'; import PrimalMenu from '../../PrimalMenu/PrimalMenu'; import { hookForDev } from '../../../lib/devTools'; +import NoteContextMenu from '../NoteContextMenu'; +import { getScreenCordinates } from '../../../utils'; -const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: string }> = (props) => { +const NoteFooter: Component<{ note: PrimalNote, id?: string }> = (props) => { const account = useAccountContext(); const toast = useToastContext(); @@ -222,7 +224,7 @@ const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: stri return; } - const newLeft = 116; + const newLeft = 120; const newTop = -8; smallZapAnimation.style.left = `${newLeft}px`; @@ -257,7 +259,7 @@ const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: stri return; } - const newLeft = 20; + const newLeft = 24; const newTop = -35; medZapAnimation.style.left = `${newLeft}px`; @@ -372,16 +374,19 @@ const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: stri }); - createEffect(() => { - if (props.doCustomZap) { - setIsCustomZap(true); - } - }); - const [showSmallZapAnim, setShowSmallZapAnim] = createSignal(false); const [showMedZapAnim, setShowMedZapAnim] = createSignal(false); const [hideZapIcon, setHideZapIcon] = createSignal(false); + + let repostMenu: HTMLDivElement | undefined; + + const determineOrient = () => { + const coor = getScreenCordinates(repostMenu); + const height = 100; + return (coor.y || 0) + height < window.innerHeight + window.scrollY ? 'down' : 'up'; + } + return (
@@ -440,7 +445,10 @@ const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: stri onClick={showRepostMenu} title={reposts().toLocaleString()} > -
+
+
+ { + setIsCustomZap(true); + setTimeout(() => setIsCustomZap(false), 10); + }} + /> +
+ { + onConfirm={(amount: number) => { setIsCustomZap(false); setZappedAmount(() => amount || 0); setZappedNow(true); setZapped(true); animateZap(); }} - onSuccess={(amount) => { + onSuccess={(amount: number) => { setIsCustomZap(false); setIsZapping(false); // setZappedAmount(() => amount || 0); @@ -478,7 +497,7 @@ const NoteFooter: Component<{ note: PrimalNote, doCustomZap?: boolean, id?: stri setHideZapIcon(false); setZapped(true); }} - onFail={(amount) => { + onFail={(amount: number) => { setZappedAmount(() => -(amount || 0)); setZappedNow(true); setIsCustomZap(false); diff --git a/src/components/Note/NoteHeader/NoteHeader.module.scss b/src/components/Note/NoteHeader/NoteHeader.module.scss index c615aa0..c77eec1 100644 --- a/src/components/Note/NoteHeader/NoteHeader.module.scss +++ b/src/components/Note/NoteHeader/NoteHeader.module.scss @@ -28,7 +28,6 @@ } .postInfo { display: flex; - flex-direction: column; font-size: 14px; line-height: 16px; font-weight: 400; @@ -117,7 +116,6 @@ background-color: var(--text-secondary-2); -webkit-mask: url(../../../assets/icons/context.svg) no-repeat 0 / 100%; mask: url(../../../assets/icons/context.svg) no-repeat 0 / 100%; - } &:hover { diff --git a/src/components/Note/NoteHeader/NoteHeader.tsx b/src/components/Note/NoteHeader/NoteHeader.tsx index a3c8a7f..a041a75 100644 --- a/src/components/Note/NoteHeader/NoteHeader.tsx +++ b/src/components/Note/NoteHeader/NoteHeader.tsx @@ -217,6 +217,17 @@ const NoteHeader: Component<{ note: PrimalNote, openCustomZap?: () => void, id?: + + + {nip05Verification(props.note.user)} + + + void, id?:
- - - {nip05Verification(props.note.user)} - -
diff --git a/src/components/Note/NotePrimary/NotePrimary.module.scss b/src/components/Note/NotePrimary/NotePrimary.module.scss index 160a6a9..04075c1 100644 --- a/src/components/Note/NotePrimary/NotePrimary.module.scss +++ b/src/components/Note/NotePrimary/NotePrimary.module.scss @@ -1,21 +1,14 @@ -.border { - background: var(--brand-gradient-vertical); - border-radius: 4px 0px 0px 4px; - width: 4px; - position: absolute; - top: 0; - left: 0; - height: 100%; -} - .post { position: relative; background-color: var(--background-card); - margin-top: 8px; display: flex; flex-direction: column; - padding: 16px 20px; - border-radius: 0px 4px 4px 0px; + padding: 12px; + padding-top: 0; + border-radius: 0; + border: 1px solid var(--devider); + border-top: none; + border-bottom: none; .content { grid-area: content; diff --git a/src/components/Note/NoteReplyToHeader.tsx b/src/components/Note/NoteReplyToHeader.tsx new file mode 100644 index 0000000..f992a4c --- /dev/null +++ b/src/components/Note/NoteReplyToHeader.tsx @@ -0,0 +1,50 @@ +import { A } from '@solidjs/router'; +import { Component, createMemo, createSignal, Show } from 'solid-js'; +import { PrimalNote, PrimalRepost, PrimalUser } from '../../types/primal'; +import ParsedNote from '../ParsedNote/ParsedNote'; +import NoteFooter from './NoteFooter/NoteFooter'; +import NoteHeader from './NoteHeader/NoteHeader'; + +import styles from './Note.module.scss'; +import { useThreadContext } from '../../contexts/ThreadContext'; +import { useIntl } from '@cookbook/solid-intl'; +import { authorName, nip05Verification, truncateNpub, userName } from '../../stores/profile'; +import { note as t } from '../../translations'; +import { hookForDev } from '../../lib/devTools'; +import Avatar from '../Avatar/Avatar'; +import { date } from '../../lib/dates'; +import VerificationCheck from '../VerificationCheck/VerificationCheck'; + +const NoteReplyHeader: Component<{ + note: PrimalNote, + id?: string, +}> = (props) => { + const intl = useIntl(); + + const rootAuthor = createMemo(() => { + const replyTo = props.note.replyTo; + const mentions = props.note.mentionedNotes; + + if (replyTo && mentions && mentions[replyTo]) { + return mentions[replyTo].user; + } + }); + + return ( + + + + {intl.formatMessage(t.reply)} +   + + @{userName(rootAuthor())} + + + + ) +} + +export default hookForDev(NoteReplyHeader); diff --git a/src/components/Note/NoteRepostHeader.tsx b/src/components/Note/NoteRepostHeader.tsx new file mode 100644 index 0000000..87397f2 --- /dev/null +++ b/src/components/Note/NoteRepostHeader.tsx @@ -0,0 +1,48 @@ +import { A } from '@solidjs/router'; +import { Component, createSignal, Show } from 'solid-js'; +import { PrimalNote, PrimalRepost, PrimalUser } from '../../types/primal'; +import ParsedNote from '../ParsedNote/ParsedNote'; +import NoteFooter from './NoteFooter/NoteFooter'; +import NoteHeader from './NoteHeader/NoteHeader'; + +import styles from './Note.module.scss'; +import { useThreadContext } from '../../contexts/ThreadContext'; +import { useIntl } from '@cookbook/solid-intl'; +import { authorName, nip05Verification, truncateNpub } from '../../stores/profile'; +import { note as t } from '../../translations'; +import { hookForDev } from '../../lib/devTools'; +import NoteReplyHeader from './NoteHeader/NoteReplyHeader'; +import Avatar from '../Avatar/Avatar'; +import { date } from '../../lib/dates'; +import VerificationCheck from '../VerificationCheck/VerificationCheck'; + +const NoteRepostHeader: Component<{ + repost?: PrimalRepost, + id?: string, +}> = (props) => { + const intl = useIntl(); + + const reposterName = () => { + if (!props.repost) { + return ''; + } + + return authorName(props.repost.user); + } + + return ( +
+
+ + + {reposterName()} + + + {intl.formatMessage(t.reposted)} + + +
+ ) +} + +export default hookForDev(NoteRepostHeader); diff --git a/src/components/Note/NotificationNote/NotificationNote.module.scss b/src/components/Note/NotificationNote/NotificationNote.module.scss index e5c5c8c..e0d950c 100644 --- a/src/components/Note/NotificationNote/NotificationNote.module.scss +++ b/src/components/Note/NotificationNote/NotificationNote.module.scss @@ -6,7 +6,7 @@ grid-template-areas: "content"; padding: 0px 16px 16px 0px; border-radius: 4px; - // width: 640px; + // width: 600px; // pointer-events: none; .content { diff --git a/src/components/PageCaption/PageCaption.module.scss b/src/components/PageCaption/PageCaption.module.scss index 3a9cbab..52f47dc 100644 --- a/src/components/PageCaption/PageCaption.module.scss +++ b/src/components/PageCaption/PageCaption.module.scss @@ -1,18 +1,25 @@ .fullHeader { display: flex; - height: 128px; + height: var(--header-height); align-items: center; justify-content: left; position: relative; - font-weight: 300; + font-weight: 400; font-size: 32px; line-height: 34px; color: var(--text-secondary); text-transform: lowercase; + border-radius: 0; + border: none; + + &.extended { + height: 126px; + } + a { - font-weight: 300; + font-weight: 400; font-size: 32px; line-height: 34px; color: var(--text-secondary); @@ -30,19 +37,27 @@ display: none; } +.title { + display: flex; + margin-left: 16px; + width: 100%; + + font-size: 32px; + font-weight: 400; + line-height: 34px; +} + @media only screen and (max-width: 720px) { .fullHeader { - justify-content: center; - font-size: 20px; - font-weight: 600; - line-height: 16px; - text-transform: capitalize; + display: flex; + justify-content: flex-start; + align-items: center; + padding-left: 20px; } .logo { display: block; left: 20px; - position: absolute; background-image: var(--logo); background-size: contain; margin-right: 0px; diff --git a/src/components/PageCaption/PageCaption.tsx b/src/components/PageCaption/PageCaption.tsx index 23610cf..f538884 100644 --- a/src/components/PageCaption/PageCaption.tsx +++ b/src/components/PageCaption/PageCaption.tsx @@ -1,13 +1,25 @@ -import { Component, JSXElement } from 'solid-js'; +import { Component, JSXElement, Show } from 'solid-js'; import { hookForDev } from '../../lib/devTools'; import styles from './PageCaption.module.scss'; -const PageCaption: Component<{ title?: string, children?: JSXElement, id?: string }> = (props) => { +const PageCaption: Component<{ + title?: string, + children?: JSXElement, + id?: string, + extended?: boolean, +}> = (props) => { return ( -
+
- {props.children || props.title || ''} +
+ + {props.children} + +
) } diff --git a/src/components/ParsedNote/ParsedNote.module.scss b/src/components/ParsedNote/ParsedNote.module.scss index e86e200..9cd3cf3 100644 --- a/src/components/ParsedNote/ParsedNote.module.scss +++ b/src/components/ParsedNote/ParsedNote.module.scss @@ -88,3 +88,7 @@ .error { color: var(--brand-1); } + +img { + background-color: var(--background-input); +} diff --git a/src/components/ParsedNote/ParsedNote.tsx b/src/components/ParsedNote/ParsedNote.tsx index 11ffc91..816f09e 100644 --- a/src/components/ParsedNote/ParsedNote.tsx +++ b/src/components/ParsedNote/ParsedNote.tsx @@ -2,6 +2,7 @@ import { A } from '@solidjs/router'; import { hexToNpub } from '../../lib/keys'; import { addLinkPreviews, + getLinkPreview, isAppleMusic, isHashtag, isImage, @@ -220,9 +221,19 @@ const ParsedNote: Component<{ return {token}; } - addLinkPreviews(token).then(preview => { - replaceLink(token, preview); - }); + const preview = getLinkPreview(token); + + const hasMinimalPreviewData = !props.noPreviews && + preview && + preview.url && + ((!!preview.description && preview.description.length > 0) || + !preview.images?.some((x:any) => x === '') || + !!preview.title + ); + + if (hasMinimalPreviewData) { + return ; + } return {token}; } @@ -379,7 +390,7 @@ const ParsedNote: Component<{ <>{noteId}{end}; } - return embeded; + return {embeded}; } if (tag[0] === 'p' && props.note.mentionedUsers && props.note.mentionedUsers[tag[1]]) { @@ -436,7 +447,7 @@ const ParsedNote: Component<{ if (hasMinimalPreviewData) { // @ts-ignore - noteHolder.querySelector(`[data-url="${url}"]`).innerHTML = (
).outerHTML; + noteHolder.querySelector(`[data-url="${url}"]`).innerHTML = (
).outerHTML; } }; diff --git a/src/components/PeopleList/PeopleList.module.scss b/src/components/PeopleList/PeopleList.module.scss index fb90885..739b8ae 100644 --- a/src/components/PeopleList/PeopleList.module.scss +++ b/src/components/PeopleList/PeopleList.module.scss @@ -4,8 +4,6 @@ top: 0px; width: 100%; height: 44px; - // background-color: var(--background-site); - background: var(--fade-gradient-vertical); z-index: 5; padding-bottom: 22px; display:flex; @@ -13,10 +11,9 @@ align-items: center; justify-content: flex-start; font-size: 18px; - font-weight: 800; + font-weight: 600; line-height: 20px; color: var(--text-secondary-2); - text-transform: uppercase; >div{ height: 22px; >span { @@ -31,7 +28,7 @@ // position: -webkit-sticky; // position: sticky; // top: 0px; - padding-top: 44px; + // padding-top: 44px; margin-bottom: 228px } @@ -51,13 +48,14 @@ } .peopleList { - margin-bottom: 33px; + margin-bottom: 16px; display: grid; - grid-template-columns: 52px 156px 64px; + grid-template-columns: 52px 148px 72px; grid-template-rows: 1fr; grid-template-areas: "avatar content follow"; grid-column-gap: 14px; text-decoration: none; + align-items: center; .avatar { grid-area: avatar; @@ -111,7 +109,7 @@ .npub { font-size: 12px; line-height: 16px; - font-weight: 300; + font-weight: 400; color: var(--text-tertiary-2); text-overflow: ellipsis; white-space: nowrap; @@ -134,12 +132,13 @@ display: flex; align-items: center; button { - width: 64px; - height: 40px; + width: 72px; + height: 28px; background: var(--brand-gradient); border-radius: 6px; padding: 0px; font-size: 12px; + font-weight: 600; line-height: 16px; margin: 0px; } diff --git a/src/components/PrimalMenu/PrimalMenu.module.scss b/src/components/PrimalMenu/PrimalMenu.module.scss index 38aae89..1cd4d94 100644 --- a/src/components/PrimalMenu/PrimalMenu.module.scss +++ b/src/components/PrimalMenu/PrimalMenu.module.scss @@ -1,18 +1,18 @@ .contextMenuOptions { position: absolute; top: 18px; - right: 8px; + right: 0px; padding: 8px; - background-color: var(--background-site); - border: solid 1px var(--text-tertiary-2); - border-radius: 4px; + background-color: var(--background-input); + border: none; + border-radius: 8px; z-index: var(--z-index-header); width: max-content; &.noteFooter { top: 26px; - left: 0px; - right: unset; + left: unset; + right: 0px; } &.profile { top: 46px; @@ -20,6 +20,32 @@ right: unset; } &.hidden { - visibility: hidden; + display: none; + } +} + +.contextMenuOptionsUp { + position: absolute; + bottom: 18px; + right: 0px; + padding: 8px; + background-color: var(--background-input); + border: none; + border-radius: 8px; + z-index: var(--z-index-header); + width: max-content; + + &.noteFooter { + bottom: 46px; + left: unset; + right: 0px; + } + &.profile { + bottom: 46px; + left: 4px; + right: unset; + } + &.hidden { + display: none; } } diff --git a/src/components/PrimalMenu/PrimalMenu.tsx b/src/components/PrimalMenu/PrimalMenu.tsx index 69cdc9d..8707e70 100644 --- a/src/components/PrimalMenu/PrimalMenu.tsx +++ b/src/components/PrimalMenu/PrimalMenu.tsx @@ -1,4 +1,4 @@ -import { Component, For } from "solid-js"; +import { Component, createEffect, createSignal, For, onMount } from "solid-js"; import { hookForDev } from "../../lib/devTools"; import { MenuItem } from "../../types/primal"; import styles from "./PrimalMenu.module.scss"; @@ -9,6 +9,7 @@ const PrimalMenu: Component<{ id: string, items: MenuItem[], position?: 'note_footer' | 'profile', + orientation?: 'up' | 'down', reverse?: boolean, hidden?: boolean, }> = (props) => { @@ -33,10 +34,18 @@ const PrimalMenu: Component<{ return ''; } + const orientationClass = () => { + if (!props.orientation || props.orientation == 'down') { + return styles.contextMenuOptions + } + + return styles.contextMenuOptionsUp + }; + return (
{item => ( diff --git a/src/components/PrimalMenu/PrimalMenuItem.module.scss b/src/components/PrimalMenu/PrimalMenuItem.module.scss index 4aaa4a1..2cd56cc 100644 --- a/src/components/PrimalMenu/PrimalMenuItem.module.scss +++ b/src/components/PrimalMenu/PrimalMenuItem.module.scss @@ -6,41 +6,38 @@ align-items: center; text-align: left; - background-color: var(--background-site); + background-color: var(--background-input); border: none; - border-radius: 2px; + border-radius: 0; + font-size: 16px; font-weight: 400; - font-size: 14px; - line-height: 16px; - color: var(--text-secondary-2); + line-height: 20px; + color: var(--text-primary); padding: 10px 12px; margin: 0px; - min-width: 196px; + min-width: 220px; div { display: inline-block; width: 16px; height: 16px; - background-color: var(--text-secondary); + background-color: var(--text-primary); } &:hover, &:focus { - background-color: var(--background-input); + background-color: var(--subtile-devider); color: var(--text-primary); - - div { - background-color: var(--text-primary); - } + border-radius: 8px; } &.warning { - color: var(--warning-color); + color: var(--warning-bright); div { - background-color: var(--warning-color); + background-color: var(--warning-bright); } &:hover, &:focus { - background-color: color-mix(in srgb, var(--warning-color) 25%, var(--background-site)); + background-color: var(--warning-dim); } } @@ -54,3 +51,9 @@ } } + +.separator { + border-top: 1px solid var(--subtile-devider); + width: 100%; + height: 0px; +} diff --git a/src/components/PrimalMenu/PrimalMenuItem.tsx b/src/components/PrimalMenu/PrimalMenuItem.tsx index 046052b..ef26763 100644 --- a/src/components/PrimalMenu/PrimalMenuItem.tsx +++ b/src/components/PrimalMenu/PrimalMenuItem.tsx @@ -29,22 +29,28 @@ const PrimalMenuItem: Component<{ onMount(getIcon); return ( -
} > - - {props.item.label} - - -
- - + + ) } diff --git a/src/components/ProfileContact/ProfileContact.module.scss b/src/components/ProfileContact/ProfileContact.module.scss index 051b3be..c2eb451 100644 --- a/src/components/ProfileContact/ProfileContact.module.scss +++ b/src/components/ProfileContact/ProfileContact.module.scss @@ -1,45 +1,57 @@ .profileContact { display: flex; align-items: center; - justify-content: stretch; + justify-content: space-between; border-bottom: 1px solid var(--background-input); - padding-block: 12px; + padding: 12px; + width: 600px; .info { display: flex; - flex-grow: 8; justify-content: space-between; text-decoration: none; padding-left: 8px; padding-right: 16px; - .profileInfo { + .personal { display: flex; - flex-direction: column; + justify-content: flex-start; - .name { - color: var(--text-primary); - font-size: 16px; - font-weight: 700; - line-height: 16px; - } + .profileInfo { + display: flex; + flex-direction: column; + padding-left: 8px; - .nip05 { - color: var(--text-tertiary-2); - font-size: 14px; - font-weight: 400; - line-height: 14px; - span { - display: inline-block; - width: 440px; - overflow: hidden; - text-overflow: ellipsis; - word-wrap: normal; + .name { + color: var(--text-primary); + font-size: 16px; + font-weight: 700; + line-height: 16px; + } + + .nip05 { + color: var(--text-tertiary-2); + font-size: 14px; + font-weight: 400; + line-height: 14px; + span { + display: inline-block; + max-width: 362px; + overflow: hidden; + text-overflow: ellipsis; + word-wrap: normal; + } } } } + } + + .action { + display: flex; + justify-content: flex-end; .stats { + margin-right: 8px; .number { color: var(--text-primary); text-align: right; diff --git a/src/components/ProfileContact/ProfileContact.tsx b/src/components/ProfileContact/ProfileContact.tsx index d3bb12c..d82f789 100644 --- a/src/components/ProfileContact/ProfileContact.tsx +++ b/src/components/ProfileContact/ProfileContact.tsx @@ -27,25 +27,26 @@ const ProfileContact: Component<{ return (
- - - - -
-
{userName(props.profile)}
-
- - - {nip05Verification(props.profile)} - - -
-
+
+ +
+
{userName(props.profile)}
+
+ + + {nip05Verification(props.profile)} + + +
+
+
+
+
@@ -56,9 +57,6 @@ const ProfileContact: Component<{
- - -
diff --git a/src/components/ProfileTabs/ProfileTabs.module.scss b/src/components/ProfileTabs/ProfileTabs.module.scss index 8eae7fe..85a765c 100644 --- a/src/components/ProfileTabs/ProfileTabs.module.scss +++ b/src/components/ProfileTabs/ProfileTabs.module.scss @@ -5,10 +5,12 @@ justify-content: space-between; align-items: center; padding-inline: 8px; - background-color: var(--background-card); + // background-color: var(--background-card); width: 100%; - border-radius: 0 0 8px 8px; + border-radius: 0; padding-top: 22px; + border: 1px solid var(--devider); + border-top: none; } .profileTab { @@ -35,7 +37,7 @@ top: 70px; left: 0; border-radius: 2px 2px 0px 0px; - background: var(--accent-1); + background: var(--accent); transition: all 250ms; } @@ -52,7 +54,7 @@ } .statName { - font-weight: 300; + font-weight: 400; font-size: 14px; line-height: 16px; color: var(--text-tertiary-2); @@ -72,7 +74,7 @@ display: flex; justify-content: center; align-items: center; - margin-top: 40px; + padding-top: 40px; button { margin: 0; @@ -100,7 +102,8 @@ justify-content: space-between; border-bottom: 1px solid var(--background-input); padding-block: 12px; - width: min(640px, 100%); + padding-inline: 20px; + width: min(600px, 100%); text-decoration: none; .zapInfo { @@ -173,7 +176,9 @@ } .totalSats { - margin-block: 16px; + padding-top: 16px; + padding-left: 16px; + margin-bottom: 16px; .totalSatsLabel { color: var(--text-tertiary); font-size: 18px; @@ -194,10 +199,14 @@ } } +.tabContent { + border-inline: 1px solid var(--devider); + min-height: 100vh; +} + .profileRelays { border-radius: 8px; overflow: hidden; - margin-top: 8px; .profileRelay { display: flex; align-items: center; @@ -244,6 +253,11 @@ padding-top: 22px; } +.loader { + min-height: 60px; + padding-top: 40px; + background: none; +} @media only screen and (max-width: 720px) { .profileTab { diff --git a/src/components/ProfileTabs/ProfileTabs.tsx b/src/components/ProfileTabs/ProfileTabs.tsx index fe12c1d..f64242a 100644 --- a/src/components/ProfileTabs/ProfileTabs.tsx +++ b/src/components/ProfileTabs/ProfileTabs.tsx @@ -229,7 +229,7 @@ const ProfileTabs: Component<{
+
}> diff --git a/src/components/ProfileWidget/ProfileWidget.module.scss b/src/components/ProfileWidget/ProfileWidget.module.scss index 309e615..65f7271 100644 --- a/src/components/ProfileWidget/ProfileWidget.module.scss +++ b/src/components/ProfileWidget/ProfileWidget.module.scss @@ -1,56 +1,36 @@ .userProfile { - display: grid; - width: 146px; - height: 46px; - grid-template-columns: 42px 1fr; - grid-column-gap: 5px; position: relative; + display: flex; + justify-content: flex-start; align-items: center; + width: 156px; + height: 48px; + border-radius: 24px; text-decoration: none; - - .background { - position: absolute; - top: 0; - left: 0; - width: 146px; - height: 46px; - background-color: var(--background-input); - background: linear-gradient(var(--background-input), var(--background-input)) padding-box, - var(--brand-gradient) border-box; - border-radius: 21px; - border: 1px solid transparent; - opacity: 0.5; - transition: opacity 0.4s; - - } + padding-inline: 6px; + background-color: var(--background-sheet); + border: none; + margin-left: 8px; &:hover { - .background { - opacity: 1; - transition: opacity 0.4s; - } + background-color: var(--background-input); } } -.avatar { - z-index: 1; - padding: 2px; -} .userInfo { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; - z-index: 1; - padding: 2px; + padding-left: 6px; } .userName { font-size: 12px; - line-height: 16px; font-weight: 700; - color: var(--text-primary); + line-height: 16px; + color: var(--active-reply); width: 90px; text-overflow: ellipsis; white-space: nowrap; @@ -87,13 +67,16 @@ @media only screen and (max-width: 1300px) { .userProfile { display: grid; - width: 48px; - grid-template-columns: 48px; + width: 40px; + height: 40px; + grid-template-columns: 40px; grid-column-gap: 0px; + margin: 0; + padding-inline: 2px; .background { - width: 46px; - height: 46px; + width: 40px; + height: 40px; } } diff --git a/src/components/ProfileWidget/ProfileWidget.tsx b/src/components/ProfileWidget/ProfileWidget.tsx index be72e58..2ce9f9e 100644 --- a/src/components/ProfileWidget/ProfileWidget.tsx +++ b/src/components/ProfileWidget/ProfileWidget.tsx @@ -21,9 +21,9 @@ const ProfileWidget: Component<{ id?: string }> = (props) => {
@@ -32,7 +32,6 @@ const ProfileWidget: Component<{ id?: string }> = (props) => { {trimVerification(activeUser()?.nip05)[1]}
-
diff --git a/src/components/ReplyToNote/ReplyToNote.module.scss b/src/components/ReplyToNote/ReplyToNote.module.scss index 714a3c6..8068c16 100644 --- a/src/components/ReplyToNote/ReplyToNote.module.scss +++ b/src/components/ReplyToNote/ReplyToNote.module.scss @@ -2,7 +2,8 @@ width: 100%; min-height: 120px; padding: 1px; - background: var(--brand-gradient); + padding-bottom: 16px; + border: 2px solid var(--accent); border-radius: 6px; display: block; position: relative; @@ -79,25 +80,38 @@ } } -.border { - height: 36px; - padding: 1px; - background: var(--brand-gradient); - border-radius: 6px; +.replyBox { + margin: 0px; + padding: 12px; + background-color: var(--background-card); + border: none; + border-bottom: 1px solid var(--devider); + border-radius: 0; + outline: none; + display: flex; + align-items: center; + width: calc(100% - 2px); + + .leftSideClosed { + width: 60px; + } .input { - height: 34px; width: 100%; - font-size: 18px; + height: 36px; + font-size: 16px; + font-weight: 400; line-height: 20px; margin: 0px; - border-radius: 6px; + margin-top: -2px; + border-radius: 18px; border: none; color: var(--text-tertiary); - background-color: var(--background-site); + background-color: var(--background-header-input); display: flex; align-items: center; - padding-inline: 12px; + justify-content: flex-start; + padding-inline: 16px; .userName { max-width: 408px; @@ -108,23 +122,7 @@ margin-left: 6px; } } -} -.replyBox { - margin: 4px 0px; - // padding: 30px 22px; - background-color: var(--background-card); - border: none; - outline: none; - display: grid; - grid-template-columns: 72px 1fr; -} - -.leftSideClosed { - // margin-top: -13px; - // margin-left: -1px; - padding-top: 3px; - padding-left: 2px; } .rightSideClosed { diff --git a/src/components/ReplyToNote/ReplyToNote.tsx b/src/components/ReplyToNote/ReplyToNote.tsx index b751368..bdf2ebf 100644 --- a/src/components/ReplyToNote/ReplyToNote.tsx +++ b/src/components/ReplyToNote/ReplyToNote.tsx @@ -62,25 +62,19 @@ const ReplyToNote: Component<{ } diff --git a/src/components/Search/Search.module.scss b/src/components/Search/Search.module.scss index ee19a60..5d8dd27 100644 --- a/src/components/Search/Search.module.scss +++ b/src/components/Search/Search.module.scss @@ -1,11 +1,13 @@ .search { - display: grid; - grid-template-columns: 16px 1fr; - grid-column-gap: 15px; - border-radius: 22px; - background-color: var(--background-input); + display: flex; + justify-content: flex-start; + align-items: center; + border-radius: 18px; + background-color: var(--background-header-input); width: 300px; - padding-right: 22px; + height: 36px; + margin-left: 8px; + margin-bottom: 0; &:hover { input { @@ -18,14 +20,16 @@ } input { + width: 240px; height: 36px; font-weight: 700; font-size: 16px; line-height: 20px; - padding: 0px 12px; + padding: 0; + margin-left: 10px; margin-bottom: 0px; border: none; - background-color: var(--background-input); + background-color: none; color: var(--text-tertiary); &:focus { @@ -36,46 +40,64 @@ &::placeholder { color: var(--text-tertiary); + font-size: 16px; + font-weight: 400; + line-height: 20px; } } .searchIcon { display: inline-block; - width: 16px; - height: 16px; + width: 18px; + height: 18px; margin-left: 16px; - margin-top: 10px; background-color: var(--text-tertiary); - -webkit-mask: url(../../assets/icons/search.svg) 0 0/16px 16px; - mask: url(../../assets/icons/search.svg) 0 0/16px 16px; + -webkit-mask: url(../../assets/icons/search.svg) 0 0/18px 18px; + mask: url(../../assets/icons/search.svg) 0 0/18px 18px; } } +.searchIconDark { + display: inline-block; + width: 18px; + height: 18px; + + background-color: var(--text-tertiary-2); + -webkit-mask: url(../../assets/icons/search.svg) 0 0/18px 18px; + mask: url(../../assets/icons/search.svg) 0 0/18px 18px; +} + .searchHolder { position: relative; - width: 300px; - padding-top: 26px; + width: 316px; + padding-top: 8px; + padding-bottom: 8px; + border-radius: 12px; + + &.focused { + background-color: var(--background-input); + } } .searchSuggestions { - width: 300px; - background-color: var(--background-site); - border: 1px solid var(--text-tertiary-2); - // box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.8); - border-radius: 4px; - - position: absolute; - top: 76px; + margin-top: 8px; + width: 316px; } .loadingOverlay { position: absolute; width: 100%; - height: 100%; + height: calc(100% - 96px); z-index: 10; - background-color: var(--background-site); - opacity: 0.8; + display: flex; + justify-content: center; + align-items: center; + + >div { + position: relative; + opacity: 1; + } } .searchIcon { diff --git a/src/components/Search/Search.tsx b/src/components/Search/Search.tsx index 4ac3e31..e1b3c33 100644 --- a/src/components/Search/Search.tsx +++ b/src/components/Search/Search.tsx @@ -102,10 +102,6 @@ const Search: Component<{ } createEffect(() => { - if (!isFocused()) { - return; - } - if (query().length === 0) { search?.actions.getRecomendedUsers(); return; @@ -115,7 +111,7 @@ const Search: Component<{ }); return ( -
+
-
- -
- -
-
+ - 0} - fallback={ -
} - underline={true} - /> - } - > + when={query().length > 0} + fallback={
} - underline={true} - onClick={resetQuery} + title={intl.formatMessage(t.searchNostr)} + narrow={true} + darkTitle={true} + icon={
} /> - + } + > +
} + onClick={resetQuery} + /> + + + +
+ 0}> +
+
+ +
+
@@ -176,7 +173,7 @@ const Search: Component<{ href={props.noLinks ? undefined : `/p/${user.npub}`} title={userName(user)} description={nip05Verification(user)} - icon={} + icon={} statNumber={search?.scores[user.pubkey]} statLabel={intl.formatMessage(t.followers)} onClick={() => selectUser(user)} diff --git a/src/components/Search/SearchOption.module.scss b/src/components/Search/SearchOption.module.scss index b927dd6..e848d19 100644 --- a/src/components/Search/SearchOption.module.scss +++ b/src/components/Search/SearchOption.module.scss @@ -2,52 +2,65 @@ .userResult { display: grid; grid-template-columns: 36px 1fr 60px; - padding: 8px; - margin: 4px; + padding-block: 10px; + padding-inline: 13px; + margin-inline: 4px; text-decoration: none; border-radius: 4px; cursor: pointer; &:hover, &:focus, &.highlight { - background-color: var(--background-input); + background-color: var(--subtile-devider); } .userAvatar { display: flex; align-items: center; justify-content: center; + min-height: 36px; .searchIcon { display: inline-block; width: 18px; height: 18px; - background-color: var(--text-primary); + background-color: var(--text-tertiary-2); -webkit-mask: url(../../assets/icons/search.svg) 0 0/18px 18px; mask: url(../../assets/icons/search.svg) 0 0/18px 18px; } } .userInfo { - margin-left: 6px; + margin-left: 12px; display: flex; flex-direction: column; justify-content: center; - max-width: 172px; + max-width: 166px; } .userName { font-weight: 700; - font-size: 14px; + font-size: 15px; line-height: 16px; color: var(--text-primary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + + &.darkTitle { + color: var(--text-tertiary); + } } .verification { font-weight: 400; - font-size: 14px; - line-height: 16px; - color: var(--text-secondary-2); + font-size: 12px; + line-height: 12px; + color: var(--text-tertiary); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .userStats { @@ -56,7 +69,7 @@ align-items: flex-end; .followerNumber { font-weight: 700; - font-size: 12px; + font-size: 15px; line-height: 16px; color: var(--text-primary) } @@ -64,8 +77,8 @@ .followerLabel { font-weight: 400; font-size: 12px; - line-height: 14px; - color: var(--text-secondary-2); + line-height: 12px; + color: var(--text-tertiary); } } } @@ -73,3 +86,7 @@ .underline { border-bottom: 1px solid var(--subtile-devider); } + +.narrow { + padding-block: 4px; +} diff --git a/src/components/Search/SearchOption.tsx b/src/components/Search/SearchOption.tsx index 9a56b7f..2229d9a 100644 --- a/src/components/Search/SearchOption.tsx +++ b/src/components/Search/SearchOption.tsx @@ -16,6 +16,8 @@ const SearchOption: Component<{ statNumber?: number, statLabel?: string, underline?: boolean, + darkTitle?: boolean, + narrow?: boolean, onClick?: (e?: MouseEvent) => void, highlighted?: boolean, id?: string, @@ -24,7 +26,8 @@ const SearchOption: Component<{ const Content: Component<{ children: JSXElement }> = (prp) => { const klass = () => `${styles.userResult} ${props.underline ? styles.underline : ''} - ${props.highlighted ? styles.highlight : ''}`; + ${props.highlighted ? styles.highlight : ''} + ${props.narrow ? styles.narrow : ''}`; return (
-
+
{props.title}
0}>
- {truncateName(props.description || '')} + {props.description || ''}
diff --git a/src/components/SelectionBox/SelectionBox.module.scss b/src/components/SelectionBox/SelectionBox.module.scss new file mode 100644 index 0000000..bd580fc --- /dev/null +++ b/src/components/SelectionBox/SelectionBox.module.scss @@ -0,0 +1,97 @@ +.checkIcon { + width: 16px; + height: 16px; + display: inline-block; + margin-inline: 8px; + background-color: var(--text-primary); + -webkit-mask: url(../../assets/icons/check.svg) no-repeat 0 / 80%; + mask: url(../../assets/icons/check.svg) no-repeat 0 / 80%; +} + +.selectionIcon { + width: 10px; + height: 10px; + display: inline-block; + margin-inline: 4px; + background-color: var(--text-secondary); + -webkit-mask: url(../../assets/icons/caret.svg) no-repeat 0 0/ 10px 10px; + mask: url(../../assets/icons/caret.svg) no-repeat 0 0/ 10px 10px; +} + +.selectionBox { + position: relative; +} + +.trigger { + background-color: var(--background-site); + margin: 0; + padding: 0; + border: none; + color: var(--text-secondary); + font-size: 18px; + font-weight: 600; + line-height: 20px; +} + +.listbox { + background-color: var(--background-input); + color: var(--text-primary); + font-size: 15px; + font-weight: 400; + line-height: 20px; + list-style-type: none; + border: none; + border-radius: 8px; + padding-block: 8px; + padding-inline: 4px; + transform: none; + + li { + list-style: none; + &:last-child { + margin-bottom: 0; + } + } +} + +.item { + display: flex; + justify-content: flex-start; + align-items: center; + padding-block: 10px; + padding-right: 32px; + border-radius: 8px; + text-transform: capitalize; + cursor: pointer; + + &:hover, &:focus-visible { + background-color: var(--subtile-devider); + border: none; + outline: none; + } + + .indicatorWrapper { + width: 32px; + height: 20px; + } +} + +.separator { + width: 100%; + height: 2px; + border-top: 1px solid var(--subtile-devider); + padding: 0 !important; + &:hover, &:focus-visible { + background-color: var(--background-site); + border: none; + outline: none; + } +} + +@media only screen and (min-width: 720px) { + .selectionBox { + >div { + transform: translate3d(-8px, 28px, 0px) !important; + } + } +} diff --git a/src/components/SelectionBox/SelectionBox.tsx b/src/components/SelectionBox/SelectionBox.tsx new file mode 100644 index 0000000..7d4fd31 --- /dev/null +++ b/src/components/SelectionBox/SelectionBox.tsx @@ -0,0 +1,73 @@ +import { useIntl } from "@cookbook/solid-intl"; +import { Select } from "@kobalte/core"; + +// Import default styles. (All examples use this via a global import) +import "@thisbeyond/solid-select/style.css"; +import { Component } from "solid-js"; +import { hookForDev } from "../../lib/devTools"; +import { placeholders } from "../../translations"; +import { SelectionOption } from "../../types/primal"; + +import SelectionItem from "./SelectionItem"; + +// Apply custom styling. See stylesheet below. +import styles from "./SelectionBox.module.scss"; + + +const SelectionBox: Component<{ + options: SelectionOption[], + onChange: (option: any) => void, + initialValue?: string | SelectionOption, + value?: string | SelectionOption, + id?: string, +}> = (props) => { + + const defaultValue = () => { + if (typeof props.initialValue === 'string') { + return props.options.find(o => o.value === props.initialValue); + } + + return props.initialValue; + } + const value = () => { + if (!props.value) { + return defaultValue(); + } + + if (typeof props.value === 'string') { + return { label: props.value, value: props.value }; + } + + return props.value; + } + + return ( + SelectionItem(prps)} + defaultValue={defaultValue()} + value={value()} + onChange={props.onChange} + gutter={8} + > + + > + {state => state.selectedOption()?.label || ''} + + +
+
+
+ + + +
+ ); +} + +export default hookForDev(SelectionBox); diff --git a/src/components/SelectionBox/SelectionItem.tsx b/src/components/SelectionBox/SelectionItem.tsx new file mode 100644 index 0000000..6b57c04 --- /dev/null +++ b/src/components/SelectionBox/SelectionItem.tsx @@ -0,0 +1,33 @@ +import { useIntl } from "@cookbook/solid-intl"; +import { Select } from "@kobalte/core"; +import { SelectBaseItemComponentProps } from "@kobalte/core/dist/types/select/select-base"; + +// Import default styles. (All examples use this via a global import) +import "@thisbeyond/solid-select/style.css"; +import { Component, Show } from "solid-js"; +import { hookForDev } from "../../lib/devTools"; +import { placeholders } from "../../translations"; +import { FeedOption } from "../../types/primal"; + +// Apply custom styling. See stylesheet below. +import styles from "./SelectionBox.module.scss"; + +const SelectionItem: Component> = (props) => { + + return ( + + +
+ +
+ +
+ {props.item.rawValue.label} + + + ); +} + +export default hookForDev(SelectionItem); diff --git a/src/components/SettingsSidebar/SettingsSidebar.module.scss b/src/components/SettingsSidebar/SettingsSidebar.module.scss index 3e70217..3f249a7 100644 --- a/src/components/SettingsSidebar/SettingsSidebar.module.scss +++ b/src/components/SettingsSidebar/SettingsSidebar.module.scss @@ -13,19 +13,9 @@ align-items: center; justify-content: flex-start; font-size: 18px; - font-weight: 800; - line-height: 22px; - color: var(--text-secondary-2); - text-transform: uppercase; - >div{ - display: flex; - height: 22px; - >span { - color: var(--text-tertiary-2); - text-transform: lowercase; - margin-left: 6px; - } - } + font-weight: 600; + line-height: 20px; + color: var(--text-secondary); } .headingConnectedRelays { @@ -44,12 +34,13 @@ align-items: center; font-size: 14px; font-weight: 400; - line-height: 28px; + line-height: 20px; color: var(--text-secondary-2); text-align: left; + margin-bottom: 8px; .connected { - background-color: #66E205; + background-color: var(--success-bright); width: 6px; height: 6px; border-radius: 2px; @@ -57,7 +48,7 @@ } .disconnected { - background-color: #E20505; + background-color: var(--warning-bright); width: 6px; height: 6px; border-radius: 2px; @@ -91,7 +82,7 @@ font-weight: 400; margin: 2px; padding: 0px; - color: var(--warning-color); + color: var(--warning-bright); display: none; flex-direction: column; align-items: center; diff --git a/src/components/SettingsZap/SettingsZap.module.scss b/src/components/SettingsZap/SettingsZap.module.scss index 17e77b4..33fbe82 100644 --- a/src/components/SettingsZap/SettingsZap.module.scss +++ b/src/components/SettingsZap/SettingsZap.module.scss @@ -23,37 +23,30 @@ } input.zapInput { - width: 124px; + display: flex; + align-items: center; + justify-content: center; + width: 120px; height: 36px; text-align: center; margin: 0; padding: 0; - font-weight: 700; - font-size: 14px; + padding-top: 4px; + font-size: 16px; + font-weight: 600; line-height: 20px; - color: var(--text-secondary); - border: 1px solid var(--subtile-devider); - border-radius: 6px; + color: var(--text-primary); + background-color: var(--background-header-input); + border: none; + border-radius: 18px; + + &:focus { + background-color: var(--subtile-devider); + } } .restoreZaps { display: flex; justify-content: flex-start; margin-top: 36px; - - button { - background: none; - color: var(--accent-1); - width: auto; - font-size: 16px; - font-weight: 400; - line-height: 20px; - border: none; - margin: 0; - padding: 0; - - &:hover { - text-decoration: underline; - } - } } diff --git a/src/components/SettingsZap/SettingsZap.tsx b/src/components/SettingsZap/SettingsZap.tsx index e2e1247..2b6801c 100644 --- a/src/components/SettingsZap/SettingsZap.tsx +++ b/src/components/SettingsZap/SettingsZap.tsx @@ -7,6 +7,7 @@ import { useIntl } from '@cookbook/solid-intl'; import ConfirmModal from '../ConfirmModal/ConfirmModal'; import { settings as t } from '../../translations'; import { hookForDev } from '../../lib/devTools'; +import ButtonLink from '../Buttons/ButtonLink'; const SettingsZap: Component<{ id?: string }> = (props) => { @@ -79,11 +80,11 @@ const SettingsZap: Component<{ id?: string }> = (props) => {
- +
-
-
- {intl.formatMessage(placeholders.noteCallToAction)} -
+
+ {intl.formatMessage(placeholders.noteCallToAction)}
); diff --git a/src/components/SmallNote/SmallNote.module.scss b/src/components/SmallNote/SmallNote.module.scss index 3d7ed28..bb606f0 100644 --- a/src/components/SmallNote/SmallNote.module.scss +++ b/src/components/SmallNote/SmallNote.module.scss @@ -6,6 +6,7 @@ grid-template-areas: "avatar content"; grid-column-gap: 12px; width: 300px; + user-select: none; .avatar { grid-area: avatar; @@ -37,7 +38,7 @@ .name { color: var(--text-secondary-2); font-weight: 800; - max-width: 120px; + max-width: 216px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; diff --git a/src/components/StickySidebar/StickySidebar.module.scss b/src/components/StickySidebar/StickySidebar.module.scss index adae438..2586a97 100644 --- a/src/components/StickySidebar/StickySidebar.module.scss +++ b/src/components/StickySidebar/StickySidebar.module.scss @@ -8,6 +8,7 @@ height: 100%; overflow: hidden; overflow-y: scroll; + padding-left: 8px; &::-webkit-scrollbar{ display: none; diff --git a/src/components/TextInput/TextInput.module.scss b/src/components/TextInput/TextInput.module.scss index d99087d..ecdfeb7 100644 --- a/src/components/TextInput/TextInput.module.scss +++ b/src/components/TextInput/TextInput.module.scss @@ -4,6 +4,10 @@ width: 100%; min-height: 98px; + &.noExtra { + min-height: 40px; + } + .root { display: flex; flex-direction: column; @@ -18,25 +22,38 @@ } .input { - border-radius: 8px; - border: 1px solid var(--subtile-devider); - background: var(--background-input); - width: 100%; height: 40px; - - margin-top: 8px; - margin-bottom: 5px; - padding-inline: 8px !important; - - color: var(--text-secondary); - font-size: 18px; + font-size: 16px; font-weight: 400; line-height: 20px; + margin: 0px; + border-radius: 20px; + border: none; + color: var(--text-primary); + background-color: var(--background-header-input); + display: flex; + align-items: center; + justify-content: flex-start; + padding-inline: 16px; + + &::placeholder { + color: var(--text-tertiary-2); + font-family: "Nacelle"; + font-size: 16px; + font-weight: 400; + line-height: 20px; + } &:focus, &:focus-visible { outline: none; - border: 1px solid var(--text-secondary); + border: none; + box-shadow: none; + &[data-invalid] { + box-shadow: 0 0 0 1px var(--warning-bright-shadow); + background-image: none; + } + } } @@ -48,7 +65,7 @@ } .errorMessage { - color: var(--warning-color); + color: var(--warning-bright); font-size: 12px; font-weight: 400; line-height: 20px; diff --git a/src/components/TextInput/TextInput.tsx b/src/components/TextInput/TextInput.tsx index 1560b14..a05fe07 100644 --- a/src/components/TextInput/TextInput.tsx +++ b/src/components/TextInput/TextInput.tsx @@ -7,6 +7,7 @@ const TextInput: Component<{ label?: string, description?: string, errorMessage?: string, + placeholder?: string, value?: string, onChange?: (value: string) => void, onKeyUp?: (e: KeyboardEvent) => void, @@ -17,10 +18,11 @@ const TextInput: Component<{ type?: string, autocomplete?: string, name?: string, + noExtraSpace?: boolean, }> = (props) => { return ( -
+
diff --git a/src/components/ThemeChooser/ThemeOption/ThemeOption.module.scss b/src/components/ThemeChooser/ThemeOption/ThemeOption.module.scss index 3a1ae2d..8871723 100644 --- a/src/components/ThemeChooser/ThemeOption/ThemeOption.module.scss +++ b/src/components/ThemeChooser/ThemeOption/ThemeOption.module.scss @@ -4,11 +4,15 @@ >p { font-size: 14px; line-height: 16px; - font-weight: 500; + font-weight: 400; color: var(--text-primary); margin-top: 8px; text-align: center; } + + img { + background: none; + } } @@ -31,7 +35,7 @@ } .selected { - border: solid 1px var(--brand-1) !important; + border: solid 1px var(--accent) !important; } .sunset { @@ -65,7 +69,7 @@ padding: 0px; align-items: center; justify-content: center; - background: var(--brand-gradient); + background: var(--accent); border-radius: 50%; >img { width: 10px; @@ -89,10 +93,10 @@ .themeUncheckedDark { @include themeUnchecked(); - background: var(--dark-input); + background-color: #222222; } .themeUncheckedLight { @include themeUnchecked(); - background: var(--light-input); + background-color: #D5D5D5; } diff --git a/src/components/Toaster/Toaster.module.scss b/src/components/Toaster/Toaster.module.scss index c695aa0..d618f38 100644 --- a/src/components/Toaster/Toaster.module.scss +++ b/src/components/Toaster/Toaster.module.scss @@ -17,34 +17,28 @@ min-height: 44px; margin: 12px; animation: fadein 0.6s; - color: white; + color: var(--text-primary-button); font-weight: 400; font-size: 18px; line-height: 20px; - border-radius: 6px; + border-radius: 22px; display: flex; justify-content: center; align-items: center; - padding-inline: 16px; + padding-inline: 24px; } .toastSuccess { @include toastMessage(); - background: linear-gradient(0deg, rgba(41, 91, 2, 0.5), rgba(41, 91, 2, 0.5)), #000000; - border-color: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4); + background: var(--success-dim); } .toastWarning { @include toastMessage(); - background: linear-gradient(0deg, rgba(144, 3, 3, 0.5), rgba(144, 3, 3, 0.5)), #000000;; - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4); + background: var(--warning-dim); } .toastInfo { @include toastMessage(); - background-color: #222222; - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4); + background-color: var(--subtile-devider); } diff --git a/src/components/VerificationCheck/VerificationCheck.module.scss b/src/components/VerificationCheck/VerificationCheck.module.scss index fbb739d..a9a7f09 100644 --- a/src/components/VerificationCheck/VerificationCheck.module.scss +++ b/src/components/VerificationCheck/VerificationCheck.module.scss @@ -15,12 +15,13 @@ display: flex; justify-content: center; align-items: center; + margin-inline: 4px; } .verifiedIconPrimal { width: 100%; height: 100%; - background: var(--brand-gradient); + background: var(--accent); -webkit-mask: url(../../assets/icons/verified.svg) no-repeat 0 / 100%; mask: url(../../assets/icons/verified.svg) no-repeat 0 / 100%; } diff --git a/src/components/VerificationCheck/VerificationCheck.tsx b/src/components/VerificationCheck/VerificationCheck.tsx index 8ee78bc..074df6c 100644 --- a/src/components/VerificationCheck/VerificationCheck.tsx +++ b/src/components/VerificationCheck/VerificationCheck.tsx @@ -34,10 +34,10 @@ const VerificationCheck: Component<{ user: PrimalUser | undefined, id?: string } }) return ( -
- + +
- -
+
+ ) } diff --git a/src/contexts/MediaContext.tsx b/src/contexts/MediaContext.tsx index 1cbe014..d8035ef 100644 --- a/src/contexts/MediaContext.tsx +++ b/src/contexts/MediaContext.tsx @@ -4,6 +4,7 @@ import { createEffect, JSXElement, onCleanup, + onMount, useContext } from "solid-js"; import { MediaEvent, MediaSize, MediaVariant, NostrEOSE, NostrEvent } from "../types/primal"; @@ -11,6 +12,7 @@ import { removeSocketListeners, isConnected, refreshSocketListeners, socket } fr import { Kind } from "../constants"; export type MediaContextStore = { + windowSize: { w: number, h: number }, media: Record, actions: { getMedia: (url: string , size?: MediaSize, animated?: boolean) => MediaVariant | undefined, @@ -20,6 +22,7 @@ export type MediaContextStore = { const initialData = { media: {}, + windowSize: { w: window.innerWidth, h: window.innerHeight }, }; export const MediaContext = createContext(); @@ -45,6 +48,10 @@ export const MediaProvider = (props: { children: JSXElement }) => { return media?.media_url; } + const onResize = () => { + updateStore('windowSize', () => ({ w: window.innerWidth, h: window.innerHeight })); + }; + // SOCKET HANDLERS ------------------------------ const onMessage = (event: MessageEvent) => { @@ -79,6 +86,15 @@ export const MediaProvider = (props: { children: JSXElement }) => { // EFFECTS -------------------------------------- + onMount(() => { + window.addEventListener('resize', onResize); + }); + + onCleanup(() => { + window.removeEventListener('resize', onResize); + }); + + createEffect(() => { if (isConnected()) { refreshSocketListeners( diff --git a/src/index.scss b/src/index.scss index 963d716..7a21154 100644 --- a/src/index.scss +++ b/src/index.scss @@ -1,256 +1,6 @@ @import "@picocss/pico/scss/pico"; -@mixin sunset_wave { - --brand-1: #FA3C3C; - --brand-2: #5B09AD; - --brand-3: #FA9A43; - --brand-gradient: linear-gradient(135deg, var(--brand-1) 0%, var(--brand-2) 100%); - --brand-gradient-vertical: linear-gradient(180deg, var(--brand-1) 0%, var(--brand-2) 100%); - --highlight-gradient: linear-gradient(137.63deg, var(--brand-3) 0%, var(--brand-1) 32.3%, var(--brand-2) 100%); - --accent-1: #CA079F; - --accent-2: #AB268E; - - --brand-text: #D5D5D5; - --background-site: #000000; - --background-card: #121212; - --background-input: #222222; - --background-modal: #00000066; - --background-embedded_card: #1A1A1A; - --border-embedded-card: #282828; - --text-primary: #FFFFFF; - --text-secondary: #AAAAAA; - --text-secondary-2: #AAAAAA; - --text-tertiary: #757575; - --text-tertiary-2: #666666; - --subtile-devider: #444444; - --check-image: url('./assets/icons/check.svg'); - - --primary: var(--accent-1); - --primary-hover: var(--accent-2); - --primary-focus: var(--background-color); - --background-color: var(--background-site); - - --active-link: var(--text-primary); - --inactive-link: var(--text-secondary); - --fade-gradient-vertical: linear-gradient(180deg, #000000FF 80%, #00000000 100%); - --fade-note-vertical: linear-gradient(180deg, #12121200, #121212FF 90%); - - --logo: url('./assets/icons/logo_fire.svg'); - --icon-follows: url('./assets/icons/follows.svg'); - --icon-tribe: url('./assets/icons/tribe.svg'); - --icon-global: url('./assets/icons/global.svg'); - --icon-network: url('./assets/icons/network.svg'); - - --icon-follows-latest: url('./assets/icons/follows_latest.svg'); - --icon-follows-popular: url('./assets/icons/follows_popular.svg'); - --icon-follows-trending: url('./assets/icons/follows_trending.svg'); - - --icon-tribe-latest: url('./assets/icons/tribe_latest.svg'); - --icon-tribe-popular: url('./assets/icons/tribe_popular.svg'); - --icon-tribe-trending: url('./assets/icons/tribe_trending.svg'); - - --icon-global-latest: url('./assets/icons/global_latest.svg'); - --icon-global-popular: url('./assets/icons/global_popular.svg'); - --icon-global-trending: url('./assets/icons/global_trending.svg'); - - --icon-network-latest: url('./assets/icons/network_latest.svg'); - --icon-network-popular: url('./assets/icons/network_popular.svg'); - --icon-network-trending: url('./assets/icons/network_trending.svg'); - - - select { - background-color: var(--background-site); - } - -} - -@mixin sunrise_wave { - --brand-1: #FA3C3C; - --brand-2: #5B09AD; - --brand-3: #5B09AD; - --brand-gradient: linear-gradient(135deg, var(--brand-1) 0%, var(--brand-2) 100%); - --brand-gradient-vertical: linear-gradient(180deg, var(--brand-1) 0%, var(--brand-2) 100%); - --highlight-gradient: linear-gradient(137.63deg, var(--brand-3) 0%, var(--brand-1) 32.3%, var(--brand-2) 100%); - --accent-1: #CA079F; - --accent-2: #AB268E; - - --brand-text: #444444; - --background-site: #F5F5F5; - --background-card: #FFFFFF; - --background-input: #E5E5E5; - --background-modal: #F5F5F566; - --background-embedded_card: #F5F5F5; - --border-embedded-card: #E5E5E5; - --text-primary: #111111; - --text-secondary: #444444; - --text-secondary-2: #666666; - --text-tertiary: #808080; - --text-tertiary-2: #808080; - --subtile-devider: #C8C8C8; - --check-image: url('./assets/icons/check-black.svg'); - - --primary: var(--accent-1); - --primary-hover: var(--accent-2); - --primary-focus: var(--background-color); - --background-color: var(--background-site); - - --active-link: var(--text-primary); - --inactive-link: var(--text-secondary); - --fade-gradient-vertical: linear-gradient(180deg, #F5F5F5FF 80%, #F5F5F500 100%); - --fade-note-vertical: linear-gradient(180deg, #FFFFFF00, #FFFFFFFF 90%); - - --logo: url('./assets/icons/logo_fire.svg'); - --icon-follows: url('./assets/icons/follows_light.svg'); - --icon-tribe: url('./assets/icons/tribe_light.svg'); - --icon-global: url('./assets/icons/global_light.svg'); - --icon-network: url('./assets/icons/network_light.svg'); - - --icon-follows-latest: url('./assets/icons/follows_latest_light.svg'); - --icon-follows-popular: url('./assets/icons/follows_popular_light.svg'); - --icon-follows-trending: url('./assets/icons/follows_trending_light.svg'); - - --icon-tribe-latest: url('./assets/icons/tribe_latest_light.svg'); - --icon-tribe-popular: url('./assets/icons/tribe_popular_light.svg'); - --icon-tribe-trending: url('./assets/icons/tribe_trending_light.svg'); - - --icon-global-latest: url('./assets/icons/global_latest_light.svg'); - --icon-global-popular: url('./assets/icons/global_popular_light.svg'); - --icon-global-trending: url('./assets/icons/global_trending_light.svg'); - - --icon-network-latest: url('./assets/icons/network_latest_light.svg'); - --icon-network-popular: url('./assets/icons/network_popular_light.svg'); - --icon-network-trending: url('./assets/icons/network_trending_light.svg'); - - select { - background-color: var(--background-site); - } -} - -@mixin midnight_wave { - --brand-1: #0090F8; - --brand-2: #4C00C7; - --brand-3: #00E0FF; - --brand-gradient: linear-gradient(135deg, var(--brand-1) 0%, var(--brand-2) 100%); - --brand-gradient-vertical: linear-gradient(180deg, var(--brand-1) 0%, var(--brand-2) 100%); - --highlight-gradient: linear-gradient(137.63deg, var(--brand-3) 0%, var(--brand-1) 32.22%, var(--brand-2) 100%); - - --accent-1: #2394EF; - --accent-2: #0C7DD8; - - --brand-text: #D5D5D5; - --background-site: #000000; - --background-card: #121212; - --background-input: #222222; - --background-modal: #00000066; - --background-embedded_card: #1A1A1A; - --border-embedded-card: #282828; - --text-primary: #FFFFFF; - --text-secondary: #AAAAAA; - --text-secondary-2: #AAAAAA; - --text-tertiary: #757575; - --text-tertiary-2: #666666; - --subtile-devider: #444444; - --card-border: #282828; - --check-image: url('./assets/icons/check.svg'); - - --primary: var(--accent-1); - --primary-hover: var(--accent-2); - --primary-focus: var(--background-color); - --background-color: var(--background-site); - - --active-link: var(--text-primary); - --inactive-link: var(--text-secondary); - --fade-gradient-vertical: linear-gradient(180deg, #000000FF 80%, #00000000 100%); - --fade-note-vertical: linear-gradient(180deg, #12121200, #121212FF 90%); - - --logo: url('./assets/icons/logo_ice.svg'); - --icon-follows: url('./assets/icons/follows.svg'); - --icon-tribe: url('./assets/icons/tribe.svg'); - --icon-global: url('./assets/icons/global.svg'); - --icon-network: url('./assets/icons/network.svg'); - - --icon-follows-latest: url('./assets/icons/follows_latest.svg'); - --icon-follows-popular: url('./assets/icons/follows_popular.svg'); - --icon-follows-trending: url('./assets/icons/follows_trending.svg'); - - --icon-tribe-latest: url('./assets/icons/tribe_latest.svg'); - --icon-tribe-popular: url('./assets/icons/tribe_popular.svg'); - --icon-tribe-trending: url('./assets/icons/tribe_trending.svg'); - - --icon-global-latest: url('./assets/icons/global_latest.svg'); - --icon-global-popular: url('./assets/icons/global_popular.svg'); - --icon-global-trending: url('./assets/icons/global_trending.svg'); - - --icon-network-latest: url('./assets/icons/network_latest.svg'); - --icon-network-popular: url('./assets/icons/network_popular.svg'); - --icon-network-trending: url('./assets/icons/network_trending.svg'); - - - select { - background-color: var(--background-site); - } -} - -@mixin ice_wave { - --brand-1: #0090F8; - --brand-2: #4C00C7; - --brand-3: #00E0FF; - --brand-gradient: linear-gradient(135deg, var(--brand-1) 0%, var(--brand-2) 100%); - --brand-gradient-vertical: linear-gradient(180deg, var(--brand-1) 0%, var(--brand-2) 100%); - --highlight-gradient: linear-gradient(137.63deg, var(--brand-3) 0%, var(--brand-1) 32.22%, var(--brand-2) 100%); - --accent-1: #2394EF; - --accent-2: #0C7DD8; - - --brand-text: #444444; - --background-site: #F5F5F5; - --background-card: #FFFFFF; - --background-input: #E5E5E5; - --background-modal: #F5F5F566; - --background-embedded_card: #F5F5F5; - --border-embedded-card: #E5E5E5; - --text-primary: #111111; - --text-secondary: #444444; - --text-secondary-2: #666666; - --text-tertiary: #808080; - --text-tertiary-2: #808080; - --subtile-devider: #C8C8C8; - --check-image: url('./assets/icons/check-black.svg'); - - --primary: var(--accent-1); - --primary-hover: var(--accent-2); - --primary-focus: var(--background-color); - --background-color: var(--background-site); - - --active-link: var(--text-primary); - --inactive-link: var(--text-secondary); - --fade-gradient-vertical: linear-gradient(180deg, #F5F5F5FF 80%, #F5F5F500 100%); - --fade-note-vertical: linear-gradient(180deg, #FFFFFF00, #FFFFFFFF 90%); - - --logo: url('./assets/icons/logo_ice.svg'); - --icon-follows: url('./assets/icons/follows_light.svg'); - --icon-tribe: url('./assets/icons/tribe_light.svg'); - --icon-global: url('./assets/icons/global_light.svg'); - --icon-network: url('./assets/icons/network_light.svg'); - - --icon-follows-latest: url('./assets/icons/follows_latest_light.svg'); - --icon-follows-popular: url('./assets/icons/follows_popular_light.svg'); - --icon-follows-trending: url('./assets/icons/follows_trending_light.svg'); - - --icon-tribe-latest: url('./assets/icons/tribe_latest_light.svg'); - --icon-tribe-popular: url('./assets/icons/tribe_popular_light.svg'); - --icon-tribe-trending: url('./assets/icons/tribe_trending_light.svg'); - - --icon-global-latest: url('./assets/icons/global_latest_light.svg'); - --icon-global-popular: url('./assets/icons/global_popular_light.svg'); - --icon-global-trending: url('./assets/icons/global_trending_light.svg'); - - --icon-network-latest: url('./assets/icons/network_latest_light.svg'); - --icon-network-popular: url('./assets/icons/network_popular_light.svg'); - --icon-network-trending: url('./assets/icons/network_trending_light.svg'); - select { - background-color: var(--background-site); - } -} +@import "./palette.scss"; /* Default theme */ :root[data-theme="dark"], @@ -292,6 +42,11 @@ --z-index-floater: 30; --z-index-overlay: 40; + --border-radius-small: 8px; + --border-radius-big: 12px; + + --central-content-width: 600px; + --sidebar-section-icon-gradient: linear-gradient(175.11deg, #FA9A43 6.94%, #FA4343 29.79%, #5B12A4 97.76%), linear-gradient(170.29deg, #CCCCCC 12.73%, #808080 94.98%), #D9D9D9; --light-input: #E5E5E5; @@ -302,6 +57,14 @@ --warning-color: #FA3C3C; --success-color: #66E205; + --left-col-w: 187px; + --center-col-w: 602px; + --right-col-w: 348px; + --full-site-w: 1137px; + --header-height: 84px; + + background-color: var(--background-site); + .mentioned_user { color: var(--accent-1); } @@ -339,15 +102,19 @@ body { margin: 0; - font-family: 'Roboto Flex', sans-serif; + font-family: 'Nacelle', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-y: scroll; background-color: var(--background-site); } +a { + color: var(--accent-links) +} + .linkish { - color: var(--accent-1); + color: var(--accent-links); } .redBorder { diff --git a/src/lib/dates.ts b/src/lib/dates.ts index c5128dc..5cc9ee9 100644 --- a/src/lib/dates.ts +++ b/src/lib/dates.ts @@ -25,32 +25,32 @@ export const date = (postTimestamp: number, style: Intl.RelativeTimeFormatStyle if ( diff > year) { const years = Math.floor(diff / year); - return { date, label: rtf.format(-years, 'years') }; + return { date, label: rtf.format(-years, 'years').replace(' ago', '') }; } if (diff > month) { const months = Math.floor(diff / month); - return { date, label: rtf.format(-months, 'months') }; + return { date, label: rtf.format(-months, 'months').replace(' ago', '') }; } if (diff > week) { const weeks = Math.floor(diff / week); - return { date, label: rtf.format(-weeks, 'weeks') }; + return { date, label: rtf.format(-weeks, 'weeks').replace(' ago', '') }; } if (diff > day) { const days = Math.floor(diff / day); - return { date, label: rtf.format(-days, 'days') }; + return { date, label: rtf.format(-days, 'days').replace(' ago', '') }; } if (diff > hour) { const hours = Math.floor(diff / hour); - return { date, label: rtf.format(-hours, 'hours') }; + return { date, label: rtf.format(-hours, 'hours').replace(' ago', '') }; } if (diff > minute) { const minutes = Math.floor(diff / minute); - return { date, label: rtf.format(-minutes, 'minutes') }; + return { date, label: rtf.format(-minutes, 'minutes').replace(' ago', '') }; } return { date, label: `${diff}s` }; diff --git a/src/lib/localStore.ts b/src/lib/localStore.ts index f779c07..b02c7ff 100644 --- a/src/lib/localStore.ts +++ b/src/lib/localStore.ts @@ -1,4 +1,4 @@ -import { NostrRelays, PrimalFeed } from "../types/primal"; +import { NostrRelays, PrimalFeed, SelectionOption } from "../types/primal"; export type LocalStore = { following: string[], @@ -10,6 +10,7 @@ export type LocalStore = { likes: string[], feeds: PrimalFeed[]; theme: string, + homeSidebarSelection: SelectionOption | undefined, }; export const emptyStorage = { @@ -22,6 +23,7 @@ export const emptyStorage = { likes: [], feeds: [], theme: 'sunset', + homeSidebarSelection: undefined, } export const storageName = (pubkey?: string) => { @@ -142,6 +144,28 @@ export const saveTheme = (pubkey: string | undefined, theme: string) => { setStorage(pubkey, store); }; +export const saveHomeSidebarSelection = (pubkey: string | undefined, selection: SelectionOption | undefined) => { + if (!pubkey) { + return; + } + + const store = getStorage(pubkey); + + store.homeSidebarSelection = selection ? { ...selection } : undefined; + + setStorage(pubkey, store); +} + +export const readHomeSidebarSelection = (pubkey: string | undefined) => { + if (!pubkey) { + return undefined; + } + const store = getStorage(pubkey) + const selection = store.homeSidebarSelection; + + return selection ? selection as SelectionOption : undefined; +}; + export const readSecFromStorage = () => { return localStorage.getItem('primalSec') || undefined; }; diff --git a/src/lib/notes.tsx b/src/lib/notes.tsx index 1dcf21c..173ec67 100644 --- a/src/lib/notes.tsx +++ b/src/lib/notes.tsx @@ -28,6 +28,10 @@ export const sanitize = (html: string) => { export const [linkPreviews, setLinkPreviews] = createStore>({}); +export const getLinkPreview = (url: string) => { + return { ...linkPreviews[url] }; +}; + export const addLinkPreviews = async (url: string) => { if (linkPreviews[url]) { return { ...linkPreviews[url] }; diff --git a/src/lib/search.ts b/src/lib/search.ts index e33f38a..57f6060 100644 --- a/src/lib/search.ts +++ b/src/lib/search.ts @@ -1,3 +1,4 @@ +import { minKnownProfiles } from "../constants"; import { sendMessage } from "../sockets"; import { sanitize } from "./notes"; @@ -51,7 +52,6 @@ export const searchFutureContent = (subid: string, query: string, since:number, } export const searchFilteredUsers = (pubkey: string | undefined, user_pubkey: string | undefined, subid: string) => { - console.log('searchFily=tered: ', pubkey, user_pubkey) if (!pubkey || !user_pubkey) { return; } @@ -63,3 +63,15 @@ export const searchFilteredUsers = (pubkey: string | undefined, user_pubkey: str {cache: ["search_filterlist", { pubkey, user_pubkey }]}, ])); }; + +export const getScoredUsers = (user_pubkey: string | undefined, selector: string, limit: number, subid: string) => { + if (!user_pubkey) { + user_pubkey = minKnownProfiles.names.primal; + } + + sendMessage(JSON.stringify([ + "REQ", + subid, + {cache: ['scored', { user_pubkey, selector }]}, + ])); +}; diff --git a/src/pages/CreateAccount.module.scss b/src/pages/CreateAccount.module.scss index 8e47c01..6d81861 100644 --- a/src/pages/CreateAccount.module.scss +++ b/src/pages/CreateAccount.module.scss @@ -4,6 +4,12 @@ padding-bottom: 20px; } +.creationContent { + padding-inline: 20px; + padding-top: 24px; + border-top: 1px solid var(--devider); +} + .fullHeader { position: relative; // background-color: var(--background-card); @@ -14,13 +20,14 @@ position: relative; width: 100%; height: 214px; + background-color: var(--background-header-input); } .banner { position: relative; width: 100%; height: 214px; - background-color: var(--background-card); + background-color: var(--background-header-input); .uploadingOverlay { position: absolute; @@ -144,17 +151,23 @@ } .uploadButton { - background: none; + display: flex; + justify-content: center; + align-items: center; + background: var(--background-input); border: none; + border-radius: 16px; outline: none; - color: var(--accent-1); - width: auto; + color: var(--text-primary); + min-width: 140px; + height: 32px; padding: 0; + padding-top: 4px; margin-block: 28px; margin-inline: 10px; font-size: 16px; font-weight: 400; - line-height: 20px; + line-height: 16px; text-transform: lowercase; >label { @@ -168,14 +181,22 @@ form { display: flex; justify-content: space-between; align-items: center; + margin-bottom: 12px; label { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; - line-height: 22px; - text-transform: uppercase; + line-height: 20px; margin: 0; + + .help { + font-size: 14px; + font-weight: 400; + line-height: 18px; + margin-left: 8px; + color: var(--text-tertiary); + } } .required { @@ -197,16 +218,14 @@ form { input, textarea { border: none; - border-radius: 8px; - background: var(--background-card); + border-radius: 18px; + background: var(--background-header-input); color: var(--text-primary); font-size: 18px; font-weight: 400; line-height: 20px; - padding-block: 14px; padding-inline: 19px; width: 100%; - margin-bottom: 16px; &:focus { outline: none; @@ -228,25 +247,37 @@ form { } } + input { + height: 36px !important; + } + + textarea { + padding-block: 8px; + min-height: 104px; + } + .inputWithPrefix { display: flex; align-items: center; - margin-bottom: var(--spacing); + margin-bottom: 32px; + background-color: var(--background-header-input); + height: 36px; + border-radius: 18px; .inputPrefix { display: flex; align-items: center; font-size: 18px; font-weight: 400; line-height: 20px; - height: 59px; + height: 36px; color: var(--text-tertiary-2); - padding-left: 19px; - border-radius: 8px 0px 0px 8px; - background: var(--background-card); + padding-left: 12px; } >input { + height: 36px; margin-bottom: 0; + background: none; padding-left: 8px; border-radius: 0px 8px 8px 0px; } @@ -404,44 +435,12 @@ form { justify-content: flex-start; button { - width: 80px; - height: 28px; - margin: 0px 16px 11px 0px; - - &.primaryButton { - border: none; - border-radius: 6px; - padding: 0px; - font-size: 14px; - line-height: 20px; - font-weight: 700; - background: var(--brand-gradient-vertical); - color: var(--text-primary); - >span { - opacity: 0.75; - } - } - - &.secondaryButton { - border: none; - border-radius: 6px; - padding: 1px; - font-size: 14px; - line-height: 20px; - font-weight: 700; - background: var(--brand-gradient-vertical); - color: var(--text-tertiary-2); - >div { - width: 100%; - height: 100%; - vertical-align: middle; - border-radius: 6px; - background-color: var(--background-card); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - } + min-width: 120px; + height: 36px; + margin-right: 16px; + >span { + display: block; + padding-top: 2px; } } @@ -484,17 +483,25 @@ form { .nameAndNip05 { display: flex; flex-direction: column; + max-width: 370px; + .name { color: var(--text-primary); font-size: 14px; font-weight: 700; line-height: 12px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } .nip05 { color: var(--text-tertiary-2); font-size: 12px; font-weight: 400; line-height: 16px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } } } @@ -516,9 +523,32 @@ form { } .stepIntro { - color: var(--text-secondary); - font-size: 16px; + color: var(--text-primary); + font-size: 15px; font-weight: 400; - line-height: 24px; + line-height: 20px; margin-bottom: 21px; } + +.stepIndicator { + width: 100%; + height: 28px; + margin-top: -22px; + display: flex; + justify-content: center; + align-items: center; + + .indicate { + width: 6px; + height: 6px; + border-radius: 3px; + margin-inline: 4px; + + &.light { + background-color: var(--accent); + } + &.dark { + background-color: var(--text-tertiary-2); + } + } +} diff --git a/src/pages/CreateAccount.tsx b/src/pages/CreateAccount.tsx index 50a2c1f..e608d3a 100644 --- a/src/pages/CreateAccount.tsx +++ b/src/pages/CreateAccount.tsx @@ -30,7 +30,7 @@ import { storeSec } from '../lib/localStore'; import { getPreConfiguredRelays } from '../lib/relays'; import CreatePinModal from '../components/CreatePinModal/CreatePinModal'; import { useSearchContext } from '../contexts/SearchContext'; -import ButtonFollow from '../components/Buttons/ButtonFollow'; +import ButtonFollow from '../components/Buttons/ButtonFlip'; import ButtonTertiary from '../components/Buttons/ButtonTertiary'; import { sendContacts } from '../lib/notes'; import ButtonSecondary from '../components/Buttons/ButtonSecondary'; @@ -38,6 +38,8 @@ import { convertToUser, nip05Verification, userName } from '../stores/profile'; import { subscribeTo } from '../sockets'; import { arrayMerge } from '../utils'; import { stringStyleToObject } from '@solid-primitives/props'; +import ButtonPrimary from '../components/Buttons/ButtonPrimary'; +import ButtonFlip from '../components/Buttons/ButtonFlip'; type AutoSizedTextArea = HTMLTextAreaElement & { _baseScrollHeight: number }; @@ -391,6 +393,15 @@ const CreateAccount: Component = () => { const intl = useIntl(); return !pubkeys.some((p) => !followed.includes(p)); }; + const toggleFollowGroup = (group: string) => { + if (isFollowingAllInGroup(group)) { + onUnfollowGroup(group); + } + else { + onFollowGroup(group) + } + }; + const onFollowGroup = (group: string) => { const pubkeys = suggestedData.groups[group] || []; let newFollows = pubkeys.filter(p => !followed.includes(p)); @@ -405,6 +416,15 @@ const CreateAccount: Component = () => { const intl = useIntl(); setFollowed(() => [ ...newFollows ]); }; + const toggleFollowAccount = (pubkey: string) => { + if (followed.includes(pubkey)) { + onUnfollow(pubkey); + } + else { + onFollow(pubkey); + } + } + const onFollow = (pubkey: string) => { setFollowed(followed.length, () => pubkey); } @@ -423,89 +443,93 @@ const CreateAccount: Component = () => { const intl = useIntl(); -
-
- - -
- {intl.formatMessage(tAccount.create.descriptions.step_one)} -
-
- -
- {intl.formatMessage(tAccount.create.descriptions.step_two)} -
-
-
-
- -
-
- - +
+
+
+
+
+
+
+
+ + +
+ {intl.formatMessage(tAccount.create.descriptions.step_one)}
- } - > - - -
- -
-
- + + +
+ {intl.formatMessage(tAccount.create.descriptions.step_two)} +
+
+ +
+
- + } + > + +
-
-
- } - > -
-
- onUpload('picture', fileUploadAvatar)} - ref={fileUploadAvatar} - hidden={true} - accept="image/*" - /> +
+
+ +
+
+
-
+
+ } + > +
+
+ onUpload('picture', fileUploadAvatar)} + ref={fileUploadAvatar} + hidden={true} + accept="image/*" + /> + +
{ const intl = useIntl(); {intl.formatMessage(tSettings.profile.uploadBanner)}
-
- +
+ +
-
- -
-
- - - * - {intl.formatMessage(tSettings.profile.required)} - -
-
-
- @ -
- -
- 0 && !isNameValid()}> -
- {intl.formatMessage(tSettings.profile.name.error)} -
-
- -
- -
- - -
+ +
- + + + * + {intl.formatMessage(tSettings.profile.required)} + +
+
+
+ @ +
+ +
+ 0 && !isNameValid()}> +
+ {intl.formatMessage(tSettings.profile.name.error)} +
+
+ +
+
{ - const target = e.target as HTMLInputElement; - target.value && setAvatarPreview(target.value); - }} + placeholder={intl.formatMessage(tSettings.profile.displayName.placeholder)} + /> + +
+
+ +
+ { + const target = e.target as HTMLInputElement; + target.value && setAvatarPreview(target.value); + }} + /> + +
+ +
+ { + const target = e.target as HTMLInputElement; + target.value && setBannerPreview(target.value); + }} + /> +
+
+ +
+
+ +
+
- + +
+