<commit_before>const nest = require('depnest')
const electron = require('electron')
const { h, when, computed } = require('mutant')

exports.gives = nest('contact.html.followToggle')
exports.needs = nest({
  'intl.sync.i18n': 'first',
  'keys.sync.id': 'first',
  'message.async.publish': 'first',
  'sbot.async.publish': 'first',
  'contact.obs.states': 'first',
  'contact.obs.followers': 'first',
  'contact.obs.blockers': 'first',
  'contact.obs.ignores': 'first'
})

exports.create = function (api) {
  const i18n = api.intl.sync.i18n
  return nest('contact.html.followToggle', function (id, opts) {
    const yourId = api.keys.sync.id()

    const states = api.contact.obs.states(yourId)
    const yourFollowers = api.contact.obs.followers(yourId)
    const ignores = api.contact.obs.ignores()

    const followsYou = computed([yourFollowers], function (yourFollowers) {
      return yourFollowers.includes(id)
    })

    const youIgnore = computed([ignores], function (ignores) {
      return !!ignores[id]
    })

    const youListening = computed([ignores], function (ignores) {
      return ignores[id] === false
    })

    const youFollow = computed([states], function (states) {
      return states[id] === true
    })

    const youBlock = computed([states], function (states) {
      return states[id] === false
    })

    const isFriends = computed([followsYou, youFollow], function (a, b) {
      return a && b
    })

    const ignoreText = when(youIgnore, ' ' + i18n('(ignored)'))
    const listeningText = when(youListening, ' ' + i18n('(listening)'))

    const showBlockButton = computed([opts && opts.block], (block) => block !== false)

    if (id !== yourId) {
      return [
        when(youBlock, [
          h('a ToggleButton -unblocking', {
            href: '#',
            title: i18n('Click to unblock'),
            'ev-click': () => setStatus(id, null, { states, ignores })
          }, [i18n('Blocked'), listeningText])
        ], [
          when(youFollow,
            h('a ToggleButton -unsubscribe', {
              href: '#',
              title: i18n('Click to unfollow'),
              'ev-click': () => setStatus(id, null, { states, ignores })
            }, [when(isFriends, i18n('Friends'), i18n('Following')), ignoreText]),
            h('a ToggleButton -subscribe', {
              href: '#',
              'ev-click': () => setStatus(id, true, { states, ignores })
            }, [when(followsYou, i18n('Follow Back'), i18n('Follow')), ignoreText])
          )
        ]),
        when(showBlockButton, h('a ToggleButton -drop -options', {
          href: '#',
          title: i18n('Click for options to block syncing with this person and/or hide their posts'),
          'ev-click': (ev) => popupContactMenu(ev.currentTarget, id, { states, ignores })
        }, i18n('Options')))
      ]
    } else {
      return []
    }
  })

  function popupContactMenu (element, id, { states, ignores }) {
    const rects = element.getBoundingClientRect()
    const status = states()[id]
    const ignoring = ignores()[id]

    // the actual listening state (use the explicit ignore if available, otherwise depends if blocking)
    const resolvedIgnoring = ignoring != null
      ? ignoring
      : status === false

    electron.remote.getCurrentWindow().webContents.getZoomFactor((factor) => {
      const menu = electron.remote.Menu.buildFromTemplate([
        {
          type: 'radio',
          label: i18n('Neutral'),
          checked: status == null,
          click: () => setStatus(id, null, { states, ignores })
        },
        {
          type: 'radio',
          label: i18n('Follow'),
          checked: status === true,
          click: () => setStatus(id, true, { states, ignores })
        },
        {
          type: 'radio',
          label: i18n('Block'),
          checked: status === false,
          click: () => setStatus(id, false, { states, ignores })
        },
        { type: 'separator' },
        {
          type: 'radio',
          label: i18n('Listen'),
          checked: !resolvedIgnoring,
          click: () => setIgnore(id, false, { states, ignores })
        },
        {
          type: 'radio',
          label: i18n('Ignore'),
          checked: resolvedIgnoring,
          click: () => setIgnore(id, true, { states, ignores })
        }
      ])
      menu.popup({
        window: electron.remote.getCurrentWindow(),
        x: Math.round(rects.left * factor),
        y: Math.round(rects.bottom * factor) + 4
      })
    })
  }

  function setStatus (id, status, { states, ignores }) {
    const currentStatus = states()[id]
    const currentIgnoring = ignores()[id]

    if (!looseMatch(status, currentStatus)) {
      const message = {
        type: 'contact',
        contact: id
      }

      if (status === true) { // FOLLOW
        message.following = true
      } else if (status === false) { // BLOCK
        message.blocking = true
      } else if (currentStatus === true) { // UNFOLLOW
        message.following = false
      } else if (currentStatus === false) { // UNBLOCK
        message.blocking = false
      }

      api.message.async.publish(message, (err) => {
        if (!err && currentIgnoring && status !== false) {<commit_msg>Fix Options drop-down in profile view.<commit_after>const nest = require('depnest')
const electron = require('electron')
const { h, when, computed } = require('mutant')

exports.gives = nest('contact.html.followToggle')
exports.needs = nest({
  'intl.sync.i18n': 'first',
  'keys.sync.id': 'first',
  'message.async.publish': 'first',
  'sbot.async.publish': 'first',
  'contact.obs.states': 'first',
  'contact.obs.followers': 'first',
  'contact.obs.blockers': 'first',
  'contact.obs.ignores': 'first'
})

exports.create = function (api) {
  const i18n = api.intl.sync.i18n
  return nest('contact.html.followToggle', function (id, opts) {
    const yourId = api.keys.sync.id()

    const states = api.contact.obs.states(yourId)
    const yourFollowers = api.contact.obs.followers(yourId)
    const ignores = api.contact.obs.ignores()

    const followsYou = computed([yourFollowers], function (yourFollowers) {
      return yourFollowers.includes(id)
    })

    const youIgnore = computed([ignores], function (ignores) {
      return !!ignores[id]
    })

    const youListening = computed([ignores], function (ignores) {
      return ignores[id] === false
    })

    const youFollow = computed([states], function (states) {
      return states[id] === true
    })

    const youBlock = computed([states], function (states) {
      return states[id] === false
    })

    const isFriends = computed([followsYou, youFollow], function (a, b) {
      return a && b
    })

    const ignoreText = when(youIgnore, ' ' + i18n('(ignored)'))
    const listeningText = when(youListening, ' ' + i18n('(listening)'))

    const showBlockButton = computed([opts && opts.block], (block) => block !== false)

    if (id !== yourId) {
      return [
        when(youBlock, [
          h('a ToggleButton -unblocking', {
            href: '#',
            title: i18n('Click to unblock'),
            'ev-click': () => setStatus(id, null, { states, ignores })
          }, [i18n('Blocked'), listeningText])
        ], [
          when(youFollow,
            h('a ToggleButton -unsubscribe', {
              href: '#',
              title: i18n('Click to unfollow'),
              'ev-click': () => setStatus(id, null, { states, ignores })
            }, [when(isFriends, i18n('Friends'), i18n('Following')), ignoreText]),
            h('a ToggleButton -subscribe', {
              href: '#',
              'ev-click': () => setStatus(id, true, { states, ignores })
            }, [when(followsYou, i18n('Follow Back'), i18n('Follow')), ignoreText])
          )
        ]),
        when(showBlockButton, h('a ToggleButton -drop -options', {
          href: '#',
          title: i18n('Click for options to block syncing with this person and/or hide their posts'),
          'ev-click': (ev) => popupContactMenu(ev.currentTarget, id, { states, ignores })
        }, i18n('Options')))
      ]
    } else {
      return []
    }
  })

  function popupContactMenu (element, id, { states, ignores }) {
    const rects = element.getBoundingClientRect()
    const status = states()[id]
    const ignoring = ignores()[id]

    // the actual listening state (use the explicit ignore if available, otherwise depends if blocking)
    const resolvedIgnoring = ignoring != null
      ? ignoring
      : status === false

    const factor = electron.remote.getCurrentWindow().webContents.getZoomFactor()
    const menu = electron.remote.Menu.buildFromTemplate([
      {
        type: 'radio',
        label: i18n('Neutral'),
        checked: status == null,
        click: () => setStatus(id, null, { states, ignores })
      },
      {
        type: 'radio',
        label: i18n('Follow'),
        checked: status === true,
        click: () => setStatus(id, true, { states, ignores })
      },
      {
        type: 'radio',
        label: i18n('Block'),
        checked: status === false,
        click: () => setStatus(id, false, { states, ignores })
      },
      { type: 'separator' },
      {
        type: 'radio',
        label: i18n('Listen'),
        checked: !resolvedIgnoring,
        click: () => setIgnore(id, false, { states, ignores })
      },
      {
        type: 'radio',
        label: i18n('Ignore'),
        checked: resolvedIgnoring,
        click: () => setIgnore(id, true, { states, ignores })
      }
    ])
    menu.popup({
      window: electron.remote.getCurrentWindow(),
      x: Math.round(rects.left * factor),
      y: Math.round(rects.bottom * factor) + 4
    })
  }

  function setStatus (id, status, { states, ignores }) {
    const currentStatus = states()[id]
    const currentIgnoring = ignores()[id]

    if (!looseMatch(status, currentStatus)) {
      const message = {
        type: 'contact',
        contact: id
      }

      if (status === true) { // FOLLOW
        message.following = true
      } else if (status === false) { // BLOCK
        message.blocking = true
      } else if (currentStatus === true) { // UNFOLLOW
        message.following = false
      } else if (currentStatus === false) { // UNBLOCK
        message.blocking = false
      }

      api.message.async.publish(message, (err) => {
        if (!err && currentIgnoring && status !== false) {
{'fraction_non_alphanumeric': 0.15485664972672356, 'fraction_numerical': 0.007479144692683863, 'mean_word_length': 2.3929733246584255, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3857676', 'n_tokens_mistral': 3172, 'n_tokens_neox': 3035, 'n_words': 733}