From f04ecc761858405f7315848e719cf48b3aaa902c Mon Sep 17 00:00:00 2001 From: Wes Johnson Date: Thu, 1 Feb 2024 00:54:15 -0500 Subject: [PATCH] initial pass at post tagging framework & doc --- scripts/zod-json-schema.ts | 2 +- site/src/components/ContentBox.astro | 7 ++ site/src/components/OpacityOverlay.astro | 2 +- site/src/components/StructuredText.astro | 9 -- .../content/enabler/anthony-housefather.json | 90 +++++++++++++++++-- site/src/content/enabler/hillel-fuld.json | 82 ++++++++++------- site/src/content/enabler/scott-aitchison.json | 22 +++-- site/src/content/enabler/tal-broda.json | 33 ++++--- site/src/layouts/ContentPageLayout.astro | 12 ++- site/src/lib/constants/strings.json | 7 +- site/src/lib/constants/strings.ts | 18 +++- site/src/lib/server/posts.ts | 2 +- site/src/lib/shared/structured-text.ts | 1 - site/src/pages/docs/editorial.astro | 72 +++++++++++++++ site/src/pages/index.astro | 21 ++++- site/src/schemas/enabler.json | 17 +++- site/src/schemas/enabler.ts | 10 ++- 17 files changed, 323 insertions(+), 84 deletions(-) create mode 100644 site/src/pages/docs/editorial.astro diff --git a/scripts/zod-json-schema.ts b/scripts/zod-json-schema.ts index 8acc021..c0d659d 100644 --- a/scripts/zod-json-schema.ts +++ b/scripts/zod-json-schema.ts @@ -10,7 +10,7 @@ const modules = zodFiles.stdout .map((line: string) => line.trim()); modules.forEach((fileName: string) => { - if (fileName) { + if (fileName && fileName.endsWith(".ts")) { const { schema, name } = require(`../site/src/schemas/${fileName}`); const jsonSchema = zodToJsonSchema(schema, name); fs.writeFileSync( diff --git a/site/src/components/ContentBox.astro b/site/src/components/ContentBox.astro index 1a33890..69047d5 100644 --- a/site/src/components/ContentBox.astro +++ b/site/src/components/ContentBox.astro @@ -14,4 +14,11 @@ border-radius: 8px; box-shadow: 5px 5px 10px rgba(0, 0, 0, 50%); } + p { + margin: 0; + margin-bottom: 2rem; + } + p:last-of-type { + margin-bottom: 0; + } diff --git a/site/src/components/OpacityOverlay.astro b/site/src/components/OpacityOverlay.astro index bdc3b15..a069b5b 100644 --- a/site/src/components/OpacityOverlay.astro +++ b/site/src/components/OpacityOverlay.astro @@ -9,7 +9,7 @@ const {} = Astro.props; .opacity-overlay { pointer-events: none; z-index: 0; - position: absolute; + position: fixed; top: 0; left: 0; right: 0; diff --git a/site/src/components/StructuredText.astro b/site/src/components/StructuredText.astro index 717155b..a0c8c86 100644 --- a/site/src/components/StructuredText.astro +++ b/site/src/components/StructuredText.astro @@ -19,8 +19,6 @@ const { parts } = Astro.props;   ) : part.type === "break" ? ( - ) : part.type === "para" ? ( -

{part.text}

) : ( part.text ) @@ -29,13 +27,6 @@ const { parts } = Astro.props;
diff --git a/site/src/lib/constants/strings.json b/site/src/lib/constants/strings.json index 9b0fadb..19ffcac 100644 --- a/site/src/lib/constants/strings.json +++ b/site/src/lib/constants/strings.json @@ -1,6 +1,5 @@ { - "mission_statement": { - "type": "text", - "text": "This website seeks to collect public statements from those supporting Israel's strategy of mass displacement, starvation, and murder of Palestinian people, and to contrast those statements with the human toll of that inhumane campaign." - } + "mission_statement": "This website seeks to collect public statements from those supporting Israel's strategy of mass displacement, starvation, and murder of Palestinian people, and to contrast those statements with the human toll of that campaign to put them in proper context.", + "editorial_intro": "In the process of collecting statements for an individual or group, we determine whether one or more of the following categories applies to their statement. If a category applies, that statement is a candidate for inclusion. If the person is sharing or boosting someone else's statement, we treat that as an endorsement of it and include it for the person doing the amplifying.", + "tag_discrimination": "Statements employing discrimination might include:" } diff --git a/site/src/lib/constants/strings.ts b/site/src/lib/constants/strings.ts index 9ec60f0..51e0e85 100644 --- a/site/src/lib/constants/strings.ts +++ b/site/src/lib/constants/strings.ts @@ -1,9 +1,23 @@ import type { StructuredText } from "../shared/structured-text"; import strings from "./strings.json"; +const isStructuredText = (part: any): part is StructuredText => { + return typeof part === "object" && typeof part.type === "string"; +}; + export const getString = (key: keyof typeof strings) => { - if (!strings[key]) { + const value = strings[key]; + if (!value) { throw new Error(`No match for string lookup by key: ${key}`); } - return strings[key] as StructuredText; + + if (isStructuredText(value)) { + return value as StructuredText; + } + + return { type: "text" as const, text: value }; +}; + +export const getStrings = (...keys: Array) => { + return keys.map((key) => getString(key)); }; diff --git a/site/src/lib/server/posts.ts b/site/src/lib/server/posts.ts index 2402c5c..1e3411e 100644 --- a/site/src/lib/server/posts.ts +++ b/site/src/lib/server/posts.ts @@ -57,7 +57,7 @@ const parsePostText = (text: string): StructuredText[] => { export const getEnhancedPosts = (posts: EnablerPost[]) => { return orderEarliestToLatest(posts) - .filter((post) => !post.skip) + .filter((post) => !!post.tags.length) .map((post) => ({ ...post, structuredText: post.text ? parsePostText(post.text) : [], diff --git a/site/src/lib/shared/structured-text.ts b/site/src/lib/shared/structured-text.ts index 11cb5e2..a1de334 100644 --- a/site/src/lib/shared/structured-text.ts +++ b/site/src/lib/shared/structured-text.ts @@ -1,6 +1,5 @@ export type StructuredText = | { type: "text"; text: string } - | { type: "para"; text: string } | { type: "url"; text: string; href: string } | { type: "space" } | { type: "break" }; diff --git a/site/src/pages/docs/editorial.astro b/site/src/pages/docs/editorial.astro new file mode 100644 index 0000000..26578a8 --- /dev/null +++ b/site/src/pages/docs/editorial.astro @@ -0,0 +1,72 @@ +--- +import ContentBox from "../../components/ContentBox.astro"; +import ContentPageLayout from "../../layouts/ContentPageLayout.astro"; +import StructuredText from "../../components/StructuredText.astro"; +import { getStrings } from "../../lib/constants/strings"; +--- + + + +

+ +

+

Discrimination

+

+ Discrimination often comes in the form of xenophobia or racism. + Islamophobia is closely related. A common example of this in recent days + is claiming pro-Palestinian protests are "hateful" or associating the + attendees as Hamas supporters by default. +

+

Dehumanisation

+

+ This category is perhaps the most insidious, as it involves broad + generalisations about a group of people that take away their individual + humanity. The common claim of "human shields" is one. Israeli Defence + Minister Yoav Gallant's statement that Gazans are "human animals" is + another very clear example. +

+

Incitement

+

+ This class of statements are hard to miss given their often aggressive + nature, and can come in the form of any of: +

    +
  • Calling for violence or persecution of a group
  • +
  • Supporting acts that could plausibly lead to a genocide
  • +
+

+

Classification

+

+ Similar to discrimination, though this is specifically about segregating + people. In the clearest case, it's the "us vs. them" environment that is + Israel-Palestine. Elsewhere and among supporter communities this can + involve assigning people to groups or excluding people who are perceived + to be different. Excluding people from making criticisms of Jewish + officials with misplaced accusations of antisemitism is another example. +

+

Polarisation

+

+ Polarisation, or the effort to divide people into sharply contrasting sets + of opinions, is a common tool by those trying to enable a cause like + genocide. It has the effect of normalising what would otherwise be extreme + views. Some examples of what would be considered polarising statements: +

    +
  • Leveraging a biased perspective or making important omissions
  • +
  • Boosting or paraphrasing government propaganda
  • +
  • + Attempting to distract or draw attention away from inconvenient + truths, war crimes, or acts that would plausibly contribute towards a + genocide +
  • +
+

+
+
+ diff --git a/site/src/pages/index.astro b/site/src/pages/index.astro index 1ff1c82..bd2e6c9 100644 --- a/site/src/pages/index.astro +++ b/site/src/pages/index.astro @@ -2,13 +2,26 @@ import ContentBox from "../components/ContentBox.astro"; import ContentPageLayout from "../layouts/ContentPageLayout.astro"; import StructuredText from "../components/StructuredText.astro"; -import { getString } from "../lib/constants/strings"; +import { getStrings } from "../lib/constants/strings"; --- - +

+ +

+

+ You can read our editorial guide to learn more + about how we decide who and what gets included in the club. +

- - + diff --git a/site/src/schemas/enabler.json b/site/src/schemas/enabler.json index a22405d..2a20f13 100644 --- a/site/src/schemas/enabler.json +++ b/site/src/schemas/enabler.json @@ -42,8 +42,18 @@ "commentary": { "type": "string" }, - "skip": { - "type": "boolean" + "tags": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "dehumanisation", + "discrimination", + "incitement", + "polarisation", + "classification" + ] + } }, "quote": { "type": "object", @@ -71,7 +81,8 @@ "required": [ "type", "href", - "date" + "date", + "tags" ], "additionalProperties": false } diff --git a/site/src/schemas/enabler.ts b/site/src/schemas/enabler.ts index bc958eb..f88c91a 100644 --- a/site/src/schemas/enabler.ts +++ b/site/src/schemas/enabler.ts @@ -17,7 +17,15 @@ export const schema = z.object({ image: z.string().optional(), imageCaption: z.string().optional(), commentary: z.string().optional(), - skip: z.boolean().optional(), + tags: z.array( + z.enum([ + "dehumanisation", + "discrimination", + "incitement", + "polarisation", + "classification", + ]) + ), quote: z .object({ text: z.string(),