about summary refs log tree commit diff
path: root/src/components/moderation
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2025-02-18 09:45:46 -0600
committerGitHub <noreply@github.com>2025-02-18 09:45:46 -0600
commitda45c42b6f1ebf0646b3327c9a4a39cd46ecb8d6 (patch)
treeee27741907d96f72601f6b9446be1e85f1b3396b /src/components/moderation
parent63ba0a436b7b2b768160ecd9e3971ed296602859 (diff)
downloadvoidsky-da45c42b6f1ebf0646b3327c9a4a39cd46ecb8d6.tar.zst
[APP-1049] show label expiration in frontend (#7738)
* Add support for label exp to LabelsOnMeDialog

* Add exp to PostAlerts, align with LabelsOnMe UI

* Bump weight

* Improve translations

* Expiry should round up

* Add a little visual alignment hack
Diffstat (limited to 'src/components/moderation')
-rw-r--r--src/components/moderation/LabelsOnMeDialog.tsx49
-rw-r--r--src/components/moderation/ModerationDetailsDialog.tsx103
2 files changed, 115 insertions, 37 deletions
diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx
index 7d1e7d032..de24729cf 100644
--- a/src/components/moderation/LabelsOnMeDialog.tsx
+++ b/src/components/moderation/LabelsOnMeDialog.tsx
@@ -5,6 +5,7 @@ import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useMutation} from '@tanstack/react-query'
 
+import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
 import {useLabelSubject} from '#/lib/moderation'
 import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
 import {makeProfileLink} from '#/lib/routes/links'
@@ -66,7 +67,7 @@ function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) {
         />
       ) : (
         <>
-          <Text style={[a.text_2xl, a.font_bold, a.pb_xs, a.leading_tight]}>
+          <Text style={[a.text_2xl, a.font_heavy, a.pb_xs, a.leading_tight]}>
             {isAccount ? (
               <Trans>Labels on your account</Trans>
             ) : (
@@ -122,6 +123,7 @@ function Label({
   const sourceName = labeler
     ? sanitizeHandle(labeler.creator.handle, '@')
     : label.src
+  const timeDiff = useGetTimeAgo({future: true})
   return (
     <View
       style={[
@@ -163,18 +165,41 @@ function Label({
             <Trans>This label was applied by you.</Trans>
           </Text>
         ) : (
-          <View style={{flexDirection: 'row'}}>
-            <Text style={[t.atoms.text_contrast_medium]}>
-              <Trans>Source: </Trans>{' '}
+          <View
+            style={[
+              a.flex_row,
+              a.justify_between,
+              a.gap_xl,
+              {paddingBottom: 1},
+            ]}>
+            <Text
+              style={[a.flex_1, a.leading_snug, t.atoms.text_contrast_medium]}
+              numberOfLines={1}>
+              <Trans>
+                Source:{' '}
+                <InlineLinkText
+                  label={sourceName}
+                  to={makeProfileLink(
+                    labeler ? labeler.creator : {did: label.src, handle: ''},
+                  )}
+                  onPress={() => control.close()}>
+                  {sourceName}
+                </InlineLinkText>
+              </Trans>
             </Text>
-            <InlineLinkText
-              label={sourceName}
-              to={makeProfileLink(
-                labeler ? labeler.creator : {did: label.src, handle: ''},
-              )}
-              onPress={() => control.close()}>
-              {sourceName}
-            </InlineLinkText>
+            {label.exp && (
+              <View>
+                <Text
+                  style={[
+                    a.leading_snug,
+                    a.text_sm,
+                    a.italic,
+                    t.atoms.text_contrast_medium,
+                  ]}>
+                  <Trans>Expires in {timeDiff(Date.now(), label.exp)}</Trans>
+                </Text>
+              </View>
+            )}
           </View>
         )}
       </View>
diff --git a/src/components/moderation/ModerationDetailsDialog.tsx b/src/components/moderation/ModerationDetailsDialog.tsx
index bdbb2daa5..658ef48d1 100644
--- a/src/components/moderation/ModerationDetailsDialog.tsx
+++ b/src/components/moderation/ModerationDetailsDialog.tsx
@@ -3,14 +3,14 @@ import {ModerationCause} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
+import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
 import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
 import {makeProfileLink} from '#/lib/routes/links'
 import {listUriToHref} from '#/lib/strings/url-helpers'
 import {isNative} from '#/platform/detection'
 import {useSession} from '#/state/session'
-import {atoms as a, useTheme} from '#/alf'
+import {atoms as a, useGutters, useTheme} from '#/alf'
 import * as Dialog from '#/components/Dialog'
-import {Divider} from '#/components/Divider'
 import {InlineLinkText} from '#/components/Link'
 import {AppModerationCause} from '#/components/Pills'
 import {Text} from '#/components/Typography'
@@ -38,9 +38,11 @@ function ModerationDetailsDialogInner({
   control: Dialog.DialogOuterProps['control']
 }) {
   const t = useTheme()
+  const xGutters = useGutters([0, 'base'])
   const {_} = useLingui()
   const desc = useModerationCauseDescription(modcause)
   const {currentAccount} = useSession()
+  const timeDiff = useGetTimeAgo({future: true})
 
   let name
   let description
@@ -128,37 +130,88 @@ function ModerationDetailsDialogInner({
     description = ''
   }
 
+  const sourceName =
+    desc.source || desc.sourceDisplayName || _(msg`an unknown labeler`)
+
   return (
-    <Dialog.ScrollableInner label={_(msg`Moderation details`)}>
-      <Text emoji style={[t.atoms.text, a.text_2xl, a.font_bold, a.mb_sm]}>
-        {name}
-      </Text>
-      <Text style={[t.atoms.text, a.text_md, a.leading_snug]}>
-        {description}
-      </Text>
+    <Dialog.ScrollableInner
+      label={_(msg`Moderation details`)}
+      contentContainerStyle={{
+        paddingLeft: 0,
+        paddingRight: 0,
+        paddingBottom: 0,
+      }}>
+      <View style={[xGutters, a.pb_lg]}>
+        <Text emoji style={[t.atoms.text, a.text_2xl, a.font_heavy, a.mb_sm]}>
+          {name}
+        </Text>
+        <Text style={[t.atoms.text, a.text_sm, a.leading_snug]}>
+          {description}
+        </Text>
+      </View>
 
       {modcause?.type === 'label' && (
-        <View style={[a.pt_lg]}>
-          <Divider />
+        <View
+          style={[
+            xGutters,
+            a.py_md,
+            a.border_t,
+            !isNative && t.atoms.bg_contrast_25,
+            t.atoms.border_contrast_low,
+            {
+              borderBottomLeftRadius: a.rounded_md.borderRadius,
+              borderBottomRightRadius: a.rounded_md.borderRadius,
+            },
+          ]}>
           {modcause.source.type === 'user' ? (
-            <Text style={[t.atoms.text, a.text_md, a.leading_snug, a.mt_lg]}>
+            <Text style={[t.atoms.text, a.text_md, a.leading_snug]}>
               <Trans>This label was applied by the author.</Trans>
             </Text>
           ) : (
             <>
-              <Text style={[t.atoms.text, a.text_md, a.leading_snug, a.mt_lg]}>
-                <Trans>
-                  This label was applied by{' '}
-                  <InlineLinkText
-                    label={desc.source || _(msg`an unknown labeler`)}
-                    to={makeProfileLink({did: modcause.label.src, handle: ''})}
-                    onPress={() => control.close()}
-                    style={a.text_md}>
-                    {desc.source || _(msg`an unknown labeler`)}
-                  </InlineLinkText>
-                  .
-                </Trans>
-              </Text>
+              <View
+                style={[
+                  a.flex_row,
+                  a.justify_between,
+                  a.gap_xl,
+                  {paddingBottom: 1},
+                ]}>
+                <Text
+                  style={[
+                    a.flex_1,
+                    a.leading_snug,
+                    t.atoms.text_contrast_medium,
+                  ]}
+                  numberOfLines={1}>
+                  <Trans>
+                    Source:{' '}
+                    <InlineLinkText
+                      label={sourceName}
+                      to={makeProfileLink({
+                        did: modcause.label.src,
+                        handle: '',
+                      })}
+                      onPress={() => control.close()}>
+                      {sourceName}
+                    </InlineLinkText>
+                  </Trans>
+                </Text>
+                {modcause.label.exp && (
+                  <View>
+                    <Text
+                      style={[
+                        a.leading_snug,
+                        a.text_sm,
+                        a.italic,
+                        t.atoms.text_contrast_medium,
+                      ]}>
+                      <Trans>
+                        Expires in {timeDiff(Date.now(), modcause.label.exp)}
+                      </Trans>
+                    </Text>
+                  </View>
+                )}
+              </View>
             </>
           )}
         </View>