webview_controller.js 3.7 KB
Newer Older
1 2 3
const fs = require('fs');
const path = require('path');
const vscode = require('vscode');
F
Fatih Acet 已提交
4
const gitLabService = require('./gitlab_service');
5 6 7

let context = null;

F
Fatih Acet 已提交
8
const addDeps = ctx => {
9
  context = ctx;
F
Fatih Acet 已提交
10
};
11 12

const getNonce = () => {
F
Fatih Acet 已提交
13 14 15
  let text = '';
  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

16 17 18
  for (let i = 0; i < 32; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
F
Fatih Acet 已提交
19

20
  return text;
F
Fatih Acet 已提交
21
};
22 23 24 25 26 27 28

const getResources = () => {
  const paths = {
    appScriptUri: 'src/webview/dist/js/app.js',
    vendorUri: 'src/webview/dist/js/chunk-vendors.js',
    styleUri: 'src/webview/dist/css/app.css',
    devScriptUri: 'src/webview/dist/app.js',
F
Fatih Acet 已提交
29
  };
30

F
Fatih Acet 已提交
31
  Object.keys(paths).forEach(key => {
32 33 34 35 36 37
    const uri = vscode.Uri.file(path.join(context.extensionPath, paths[key]));

    paths[key] = uri.with({ scheme: 'vscode-resource' });
  });

  return paths;
F
Fatih Acet 已提交
38
};
39

F
Fatih Acet 已提交
40
const getIndexPath = () => {
F
Fatih Acet 已提交
41
  const isDev = !fs.existsSync(path.join(context.extensionPath, 'src/webview/dist/js/app.js'));
F
Fatih Acet 已提交
42 43

  return isDev ? 'src/webview/public/dev.html' : 'src/webview/public/index.html';
F
Fatih Acet 已提交
44
};
F
Fatih Acet 已提交
45

F
Fatih Acet 已提交
46
const replaceResources = () => {
47
  const { appScriptUri, vendorUri, styleUri, devScriptUri } = getResources();
F
Fatih Acet 已提交
48 49

  return fs
F
Fatih Acet 已提交
50 51 52 53 54 55
    .readFileSync(path.join(context.extensionPath, getIndexPath()), 'UTF-8')
    .replace(/{{nonce}}/gm, getNonce())
    .replace('{{styleUri}}', styleUri)
    .replace('{{vendorUri}}', vendorUri)
    .replace('{{appScriptUri}}', appScriptUri)
    .replace('{{devScriptUri}}', devScriptUri);
F
Fatih Acet 已提交
56
};
F
Fatih Acet 已提交
57

F
Fatih Acet 已提交
58
const createPanel = issuable => {
F
Fatih Acet 已提交
59
  const title = `${issuable.title.slice(0, 20)}...`;
F
Fatih Acet 已提交
60

F
Fatih Acet 已提交
61 62
  return vscode.window.createWebviewPanel('glWorkflow', title, vscode.ViewColumn.One, {
    enableScripts: true,
F
Fatih Acet 已提交
63
    localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'src'))],
F
Fatih Acet 已提交
64
  });
F
Fatih Acet 已提交
65
};
F
Fatih Acet 已提交
66

67 68
function sendIssuableAndDiscussions(panel, issuable, discussions, appIsReady) {
  if (!discussions || !appIsReady) return;
F
Fatih Acet 已提交
69
  panel.webview.postMessage({ type: 'issuableFetch', issuable, discussions });
70 71 72 73 74
}

async function handleCreate(panel, issuable) {
  let discussions = false;
  let appIsReady = false;
F
Fatih Acet 已提交
75
  panel.webview.onDidReceiveMessage(async message => {
76 77 78 79 80
    if (message.command === 'appReady') {
      appIsReady = true;
      sendIssuableAndDiscussions(panel, issuable, discussions, appIsReady);
    }

F
Fatih Acet 已提交
81 82
    if (message.command === 'renderMarkdown') {
      let rendered = await gitLabService.renderMarkdown(message.markdown);
83 84 85
      rendered = (rendered || '')
        .replace(/ src=".*" alt/gim, ' alt')
        .replace(/" data-src/gim, '" src');
F
Fatih Acet 已提交
86 87 88 89 90 91 92 93

      panel.webview.postMessage({
        type: 'markdownRendered',
        ref: message.ref,
        key: message.key,
        markdown: rendered,
      });
    }
F
Fatih Acet 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

    if (message.command === 'saveNote') {
      const response = await gitLabService.saveNote({
        issuable: message.issuable,
        note: message.note,
      });

      if (response.status !== false) {
        const newDiscussions = await gitLabService.fetchDiscussions(issuable);
        panel.webview.postMessage({ type: 'issuableFetch', issuable, discussions: newDiscussions });
        panel.webview.postMessage({ type: 'noteSaved' });
      } else {
        panel.webview.postMessage({ type: 'noteSaved', status: false });
      }
    }
F
Fatih Acet 已提交
109
  });
110 111 112

  discussions = await gitLabService.fetchDiscussions(issuable);
  sendIssuableAndDiscussions(panel, issuable, discussions, appIsReady);
113 114
}

115 116 117 118 119 120 121 122 123 124 125 126
async function create(issuable) {
  const panel = createPanel(issuable);
  const html = replaceResources();
  panel.webview.html = html;

  panel.onDidChangeViewState(() => {
    handleCreate(panel, issuable);
  });

  handleCreate(panel, issuable);
}

127 128
exports.addDeps = addDeps;
exports.create = create;