Wildindfw
11/21/2018 - 6:02 AM

Discord Embed Generator

Discord Embed Generator

link(href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet")
a.patreon-link(href="https://patreon.com/orels1" target="_blank")
  .badge-container
    .badge-text like what you see?
    .badge-icon
    .badge-text.badge-text-bottom support me

.container
  .col-md-10.offset-md-1
    .card-deck
      .card
        .card-header Embed Editor
        .card-block
          form#form
            .form-group
              label Basic settings
              input#title.form-control(type="text", placeholder="title")
            .form-group
              input#description.form-control(type="text", placeholder="description")
            .form-group
              input#url.form-control(type="text", placeholder="url")
            .form-group
              label Color
              input#color.form-control(type="color")
            .form-group
              label Thumbnail settings
              input#icon.form-control(type="text", placeholder="icon")
            .form-group
              label Author settings
              input#author_name.form-control(type="text", placeholder="author name")
            .form-group
              input#author_url.form-control(type="text", placeholder="author link")
            .form-group
              input#author_icon.form-control(type="text", placeholder="author icon")
            .form-group
              label Fields
            .input-fields
            .form-group
              label Footer settings
              input#footer.form-control(type="text", placeholder="footer text")
  br/
  .col-md-8.offset-md-2          
    .card
      .card-header Embed Preview
      .card-block.preview
        .wrapper
          .side-colored
          .card.embed
            .card-block
              .embed-inner
  br/
  .col-md-10.offset-md-1
    .card
      .card-header Python code
      .card-block
        pre
          code.python.source
                
$(document).ready(() => {
  let switches = {
    title: false,
    url: false,
    icon: false,
  };
  
  let fields = 1;
  
  let source = ``;
  
  let embed = {
    title: 'Embed title (required)',
    author: {
      name: '',
      url: '',
      icon: ''
    },
    description: '',
    url: '',
    thumb_url: '',
    color: '',
    fields: [{
    }
    ],
    footer: ''
  };
  
  function resetEmbed() {
    $('.embed-inner').html('');
    $('.embed-footer').remove();
    $('.embed-thumb').remove();
  }
  
  function updateEmbed(embed) {
    resetEmbed();
    
    // add basic embed generation to source
    source = `embed=discord.Embed(`;

    if (embed.url) {
      $('.embed-inner').append(`<div class="embed-title"><a href="${embed.url}">${embed.title}</a></div>`);
      
      // update source
      source += `title="${embed.title}", url='${embed.url}'`;
    } else {
      $('.embed-inner').append(`<div class="embed-title">${embed.title}</div>`);
      
      // update source
      source += `title="${embed.title}"`;
    }
    
    if (embed.description) {
      $('.embed-inner').append(`<div class="embed-description">${embed.description}</div>`);
      
      // update source
      source += `, description="${embed.description}"`;
    }
    
    if (embed.color) {
      $('.side-colored').css('background-color', embed.color); 
      
      // update source
      source += `, color=0x${embed.color.substr(1)}`;
    }
    
    // finished the basic setup
    source += `)\n`;
    
    if (embed.author.name) {
      // add author to source
      source += `embed.set_author(`;
      
      $('.embed-title').before(`<div class="embed-author"><a class="embed-author-name" href="${embed.author.url}">${embed.author.name}</a></div>`);
      
        // update source
        source += `name="${embed.author.name}"${embed.author.url && `, url='${embed.author.url}'`}`;
      if (embed.author.icon) {
        $('.embed-author-name').before(`<img class="embed-author-icon" src="${embed.author.icon}" />`);
        
        // update source
        source += `, icon_url='${embed.author.icon}'`;
      }
      
      // finish author
      source += `)\n`;
    }

    if (embed.thumb_url) {
      // add thumbnail
      source += `embed.set_thumbnail(`
      
      $('.card.embed .card-block').append(`<img class="embed-thumb" src="${embed.thumb_url}" />`);
      $('.embed-thumb').height($('.embed-thumb')[0].naturalHeight);
      
      // update source
      source += `url='${embed.thumb_url}'`;
      
      // finish thumbnail
      source += `)\n`;
    }

    if (embed.fields.length > 0) {
      $('.embed-inner').append(`<div class="fields"></div>`);
    }
    
    for (let field of embed.fields) {
      $('.embed-inner .fields').append(`
        <div class="field ${field.inline && 'inline'}">
          <div class="field-name">${field.name}</div>
          <div class="field-value">${field.value}</div>
        </div>
      `);
      
      // add field
      source += `embed.add_field(name="${field.name}", value="${field.value}", inline=${(field.inline && 'True') || 'False'})\n`;
    }

    if (embed.footer) {
      $('.card.embed').append(`<div class="embed-footer"><span>${embed.footer}</span></div>`);
      
      // add footer
      source += `embed.set_footer(text="${embed.footer}")\n`;
    }
    
    // add send function
    source += `await self.bot.say(embed=embed)\n`;
    
    // code
    $('.source').text(source);
    hljs.highlightBlock($('.source')[0]);
  }
  
  // run once on startup
  updateEmbed(embed);
  
  function generateInputFields(fields) {
    // generate inputs for fields
    $('.input-fields').html('');
    for (let i = 0; i < fields; i++) {
      $('.input-fields').append(`<div class="form-group row">
        <div class="col-sm-4">
          <input class="form-control" id="field-${i}-name" type="text" placeholder="name" value="${embed.fields[i].name !== undefined ? embed.fields[i].name : ''}" />
        </div>
        <div class="col-sm-4">
          <input class="form-control" id="field-${i}-value" type="text" placeholder="value" value="${embed.fields[i].value !== undefined ? embed.fields[i].value : ''}" />
        </div>
        <div class="col-sm-2">
          <div class="form-check">
            <label class="form-check-label">
              <input class="form-check-input" id="field-${i}-inline" type="checkbox" ${embed.fields[i].inline !== undefined ? 'checked="checked"' : ''}> Inline
            </label>
          </div>
        </div>
        <div class="col-sm-2">
          <button id="field-${i}-delete" class="btn btn-danger">Delete</button>
        </div>
      </div>`)
      $(`#field-${i}-name`).keyup(() => {
        updateFieldName(i, $(`#field-${i}-name`).val())
      });

      $(`#field-${i}-value`).keyup(() => {
        updateFieldValue(i, $(`#field-${i}-value`).val())
      });
      
      $(`#field-${i}-inline`).click(() => {
        updateFieldInline(i, $(`#field-${i}-inline`).is(':checked'));
      })
      
      $(`#field-${i}-delete`).click((e) => {
        e.preventDefault();
        deleteField(i);
      });
    }
    $('.input-fields').append(`<button id="add-field" class="btn btn-success">Add field</button>`);
    $('#add-field').click((e) => {
      e.preventDefault();
      addField();
    })
  }
  
  generateInputFields(fields);
  
  function updateFieldName(index, value) {
    embed.fields[index].name = value;
    updateEmbed(embed);
  }
  
  function updateFieldValue(index, value) {
    embed.fields[index].value = value;
    updateEmbed(embed);
  }
  
  function updateFieldInline(index, value) {
    embed.fields[index].inline = value;
    updateEmbed(embed);
  }
  
  function deleteField(index) {
    embed.fields.splice(index,1);
    updateEmbed(embed);
    fields -= 1;
    generateInputFields(fields);
  }
  
  function addField() {
    embed.fields.push({inline: true});
    fields += 1;
    generateInputFields(fields);
  }
  
  function updateTitle(value) {
    embed.title = value || '';
    updateEmbed(embed);
  }
  
  function updateUrl(value) {
    embed.url = value || '';
    updateEmbed(embed);
  }
  
  function updateThumb(value) {
    embed.thumb_url = value || false;
    updateEmbed(embed);
  }
  
  function updateDescription(value) {
    embed.description = value || '';
    updateEmbed(embed);
  }
  
  function updateColor(value) {
    embed.color = value || false;
    updateEmbed(embed);
  }

  function updateAuthorName(value) {
    embed.author.name = value || '';
    updateEmbed(embed);
  }

  function updateAuthorUrl(value) {
    embed.author.url = value || '';
    updateEmbed(embed);
  }

  function updateAuthorIcon(value) {
    embed.author.icon = value || '';
    updateEmbed(embed);
  }
  
  function updateFooter(value) {
    embed.footer = value || '';
    updateEmbed(embed);
  }
  
  $('#form').submit((e) => {
    e.preventDefault();
  });
  
  // checking helpers
  function addWarning(item, type, message) {
    item.addClass('form-control-warning');
    item.removeClass('form-control-success');
    item.parent().addClass('has-warning');
    item.parent().removeClass('has-success');
    if ($(`#${type}-feedback`).length === 0) {
      item.after(`<div class="form-control-feedback" id="${type}-feedback">${message}</div>`);
    }
  }
  
  function addSuccess(item, type) {
    item.removeClass('form-control-warning');
    item.addClass('form-control-success');
    item.parent().addClass('has-success');
    item.parent().removeClass('has-warning');
    $(`#${type}-feedback`).remove();
  }
  
  $('#title').keyup(() => {
    let item = $('#title');
    let title = item.val();    
    
    // preform checks
    if (title.length === 0) {
      addWarning(item, 'title', 'title cannot be empty');  
    } else {
      addSuccess(item, 'title');
      // update
      updateTitle(title);
    }
    
  });
  
  $('#url').keyup(() => {
    let item = $('#url');
    let url = item.val();
    
    if (url.substr(0,4) !== 'http' && url.length !== 0) {
      addWarning(item, 'url', 'not a valid url');
    } else {
      addSuccess(item, 'url');
      // update
      updateUrl(url);
    }
    
    
  });
  
  $('#icon').keyup(() => {
    let item = $('#icon');
    let icon = item.val();
    
    if (icon.substr(0,4) !== 'http' && icon.length !== 0) {
      addWarning(item, 'icon', 'not a valid url');
    } else {
      addSuccess(item, 'icon');
      // update
      updateThumb(icon);
    }
  });
  
  $('#description').keyup(() => {
    let item = $('#description');
    let description = item.val();
    addSuccess(item, 'description');
    // update
    updateDescription(description);
  });
  
  $('#color').change(() => {
    updateColor($('#color').val());
  });

  $('#author_name').keyup(() => {
    let item = $('#author_name');
    let author_name = item.val();
    
    addSuccess(item, 'author_name');
    // update
    updateAuthorName(author_name);
  });

  $('#author_url').keyup(() => {
    let item = $('#author_url');
    let author_url = item.val();
    
    if (author_url.substr(0,4) !== 'http' && author_url.length !== 0) {
      addWarning(item, 'author_url', 'not a valid url');
    } else {
      addSuccess(item, 'author_url');
      // update
      updateAuthorUrl(author_url);
    }
  });

  $('#author_icon').keyup(() => {
    let item = $('#author_icon');
    let author_icon = item.val();
    
    if (author_icon.substr(0,4) !== 'http' && author_icon.length !== 0) {
      addWarning(item, 'author_icon', 'not a valid url');
    } else {
      addSuccess(item, 'author_icon');
      // update
      updateAuthorIcon(author_icon);
    }
  });
  
  $('#footer').keyup(() => {
    let item = $('#footer');
    let footer = item.val();
    
    addSuccess(item, 'footer');
    // update
    updateFooter(footer);
  });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/highlight.min.js"></script>
$width: 120px
$top: 20px
$left: 20px

a.patreon-link
  display: flex
  box-sizing: border-box
  width: 100%
  height: auto
  z-index: 10
  text-decoration: none
  
.badge-container
  width: 100%
  display: flex
  flex-direction: column
  padding: 5px 10px
  background: rgba(0,0,0,0.5)
  border: 1px solid rgba(255,255,255,0.5)
  text-align: center
  
  .badge-icon
    background: url('https://s3.amazonaws.com/patreon_public_assets/toolbox/patreon_white.png') center center no-repeat
    background-size: contain
    width: 100%
    height: 20px
    
  .badge-text
    font-family: 'Lato', sans-serif
    font-size: 12px
    padding: 2px
    color: #fff
    
    &.badge-text-bottom
      position: relative
      top: -2px
    
    

.preview
  background: #36393e
  display: flex
  box-orient: vertical
  flex-direction: column
  
.wrapper
  display: flex
  max-width: 520px
  
.container
  margin-top: 50px
  
.side-colored
  width: 4px
  border-radius: 3px 0 0 3px
  background: #4f545c
  
.embed
  border-radius: 0 3px 3px 0
  background: rgba(46,48,54,.3)
  border-color: rgba(46,48,54,.6)
  display: flex
  padding: 8px 10px
  color: rgba(255,255,255,0.6)
  font-size: 14px
  
  .card-block
    padding: 0
    display: flex
    margin-bottom: 10px
  
  a
    color: #0096cf
    
  img.embed-thumb
    max-height: 80px
    max-width: 80px
    border-radius: 3px
    flex-shrink: 0
    width: auto
    object-fit: contain
    margin-left: 20px
    
  .embed-footer
    font-size: 12px
    span
      color: rgba(255,255,255,0.6)
    
  .embed-inner
    
    .embed-title
      color: #fff
    
    .embed-author
      display: flex
      align-items: center
      margin-bottom: 5px
      
      img.embed-author-icon
        margin-right: 9px
        width: 20px
        height: 20px
        object-fit: contain
        border-radius: 50%
        
      .embed-author-name
        display: inline-block
        font-weight: 600
        font-size: 14px
        color: #fff !important
        
    .fields
      display: flex
      flex-wrap: wrap
      flex-direction: row
      box-lines: miltiple
      margin-top: -10px
      
      .field
        flex: 0
        box-flex: 1
        padding-top: 10px
        max-width: 506px
        min-width: 100%
        
        &.inline
          box-flex: 1
          flex: 1
          min-width: 150px
          flex-basis: auto
        
        .field-name
          color: #fff
          font-size: 14px
          margin-bottom: 4px
          font-weight: 600
          
        .field-value
          color: rgba(255,255,255,0.7)
          font-size: 14px
          font-weight: 500
          line-height: 1.1em
          white-space: pre-wrap
          margin-top: 6px
          word-wrap: break-word
          
          
          
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/css/tether-theme-arrows-dark.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.9.0/styles/dark.min.css" rel="stylesheet" />