Files snapshot from main

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
7d2ffa Tucker McKnight
7bbc3b Tucker McKnight
b1c071 Tucker McKnight
be0819 Tucker McKnight
fc1156 Tucker McKnight
7bbc3b Tucker McKnight
fc1156 Tucker McKnight
fc1156 Tucker McKnight
fc1156 Tucker McKnight
be0819 Tucker McKnight
be0819 Tucker McKnight
be0819 Tucker McKnight
be0819 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
b1c071 Tucker McKnight
be0819 Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
7bbc3b Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
7d2ffa Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
93646a Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
5428c7 Tucker McKnight
5428c7 Tucker McKnight
31332f Tucker McKnight
5428c7 Tucker McKnight
5428c7 Tucker McKnight
5428c7 Tucker McKnight
7d2ffa Tucker McKnight
f8e00d Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
5428c7 Tucker McKnight
31332f Tucker McKnight
31332f Tucker McKnight
7d2ffa Tucker McKnight
5428c7 Tucker McKnight
5428c7 Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
5428c7 Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7d2ffa Tucker McKnight
7bbc3b Tucker McKnight
be0819 Tucker McKnight
import m from 'mithril'
import htmlPage from './common/htmlPage.ts'
import { NavHelper } from './helpers/nav.ts'

export default async (
  reposConfig: any,
  eleventyConfig: any,
  data: any,
) => {
  const date = eleventyConfig.getFilter("date")
  const slugify = eleventyConfig.getFilter("slugify")
  const lineNumbers = eleventyConfig.getFilter("lineNumbers")
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: data.currentRepo.name,
    currentRefName: data.currentRef.name,
    currentRefType: data.currentRefType,
  })

  const repo = data.currentRepo

  return await htmlPage(reposConfig, eleventyConfig, data, [
    m('div', {class: "row"},
      m('div', {class: "col-auto"},
        m('div', {class: "bezel-secondary px-3 py-2"}, [
          m('h1', {class: "fs-2"}, data.patchInfo.commit.message.split('\n')[0]),
          m('div', {class: "input-group mb-2 flex-nowrap"}, [
            m('span', {class: "font-monospace input-group-text border-info text-white text-bg-dark overflow-scroll"}, data.patchInfo.commit.hash),
            m('button', {'data-copy-text': data.patchInfo.commit.hash, class: "btn btn-info shadow-none copy-button"}, 'Copy')
          ]),
          m('p', `${data.patchInfo.commit.author} | ${date(data.patchInfo.commit.date)}`),
          m('pre', {class: "mb-0"}, data.patchInfo.commit.message)
        ])
      )
    ),
    m('div', {class: "row my-4"},
      m('div', {class: "col-auto"}, [
        m('div', {class: "form-check"}, [
          m('input', {
            class: "form-check-input",
            type: "radio",
            name: "unified",
            id: "splitModeSwitch",
            value: "split",
            onchange: "toggleUnifiedMode(this)",
            checked: true,
          }),
          m('label', {class: "form-check-label", for: "splitModeSwitch"}, 'Side-by-side'),
        ]),
        m('div', {class: "form-check"}, [
          m('input', {
            class: "form-check-input",
            type: "radio",
            name: "unified",
            id: "unifiedModeSwitch",
            value: "unified",
            onchange: "toggleUnifiedMode(this)",
          }),
          m('label', {class: "form-check-label", for: "unifiedModeSwitch"}, 'Stacked')
        ])
      ])
    ),
    m('div', {class: "row", id: "diffs"}, data.patchInfo.commit.diffs.map((hunk) => {
      // Search through the available branches and tags, seeing if we have a copy of this
      // file in the filelist for any branch or tag. Put together a list of those for
      // linking to.
      let availableInRefs = repo.branches.filter((ref) => {
        return ref.fileList.has(hunk.fileName)
      }).map((ref) => {
        return { refName: ref.name, refType: 'branch' }
      })

      availableInRefs = availableInRefs.concat(repo.tags.filter((ref) => {
        return ref.fileList.has(hunk.fileName)
      }).map((ref) => {
        return { refName: ref.name, refType: 'tag' }
      }))

      return m('div', {class: 'hunk'}, [
        m('div', [
          m('span', {class: "font-monospace fw-bold me-2"}, `${hunk.fileName}:${hunk.lineNumber}`),
          m('label', {class: 'me-2'}, 'View file in:'),
          m('div', {class: 'dropdown d-inline'}, [
            m('button', {
              class: 'btn btn-bg btn-sm dropdown-toggle',
              ['data-bs-toggle']: 'dropdown',
            }, 'Select...'),
            // TODO: use tabs for branches and tags, like in the top menu?
            // TODO: Have a special case for if availableInRefs is empty (e.g. the file has since been deleted).
            m('ul', {class: 'dropdown-menu'}, availableInRefs.map((ref) => {
              return m('li', {class: 'dropdown-item'}, m('a', {
                href: nav.file(hunk.fileName, ref)
              }, ref.refName))
            }))
          ])
        ]),
        m('div', {class: "diff d-flex"}, [
          m('div', {class: "flex-grow-1 diff-left pe-2"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'Before'),
            m('div', {class: "row"}, [
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.beforeText).map((lineNumber) => {
                  if (lineNumber === null) { return '' }
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
              m('div', {class: "col overflow-scroll"},
                m('pre', {class: "mb-0", 'data-start': hunk.lineNumber}, m('code', {'data-type': 'before', class: `code-diff line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, m.trust(hunk.beforeText)))
              )
            ])
          ]),
          m('div', {class: "diff-right flex-grow-1"}, [
            m('span', {class: 'font-monospace text-secondary'}, 'After'),
            m('div', {class: "row"},
              m('div', {class: "col-auto border-end"},
                m('pre', {class: "mb-0"}, lineNumbers(hunk.afterText).map((lineNumber) => {
                  if (lineNumber === null) { return '' }
                  return (lineNumber + hunk.lineNumber - 1).toString()
                }).join('\n'))
              ),
              m('div', {class: "col overflow-scroll"},
                m('pre', {class: "mb-0", 'data-start': hunk.lineNumber},
                  m('code', {'data-type': "after", class: `line-numbers language-${languageExtension(hunk.fileName, data.patchInfo.repoName)}`}, m.trust(hunk.afterText))
                )
              )
            )
          ])
        ])
      ])
    })),
    m('script', m.trust(`
const toggleUnifiedMode = (e) => {
  const diffs = document.getElementById('diffs')
  const afterDiffs = document.querySelectorAll('.diff-right')
  if (e.value == "unified") {
    diffs.classList.add("unified")
  }
  else {
    diffs.classList.remove("unified")
  }
}
`)
    )
  ])
}