Fix message dynamic load in the main Chat

<template>

    <template v-if="summary.title">

        <template slot="title">
          <avatar :src="summary.picture" alt=""
            class="c-header-avatar"
            size="sm"
            hasMargin
          />

          {{summary.title}}
        </template>
        <template slot="actions">
          <button class="button is-icon">

          </button>
          <button class="button is-icon">

          </button>
          <menu-parent class="level-right">
            <menu-trigger class="is-icon">

            </menu-trigger>

            <menu-content class="c-actions-content">
              <list hasMargin>
                <menu-item tag="button" itemId="hash-1" icon="heart">
                  <i18n>Option 1</i18n>
                </menu-item>
                <menu-item tag="button" itemId="hash-2" icon="heart">
                  <i18n>Option 2</i18n>
                </menu-item>
                <menu-item tag="button" itemId="hash-3" icon="heart">
                  <i18n>Option 3</i18n>
                </menu-item>
              </list>
            </menu-content>
          </menu-parent>
        </template>

          <loading />

          <conversation-greetings />
          <template v-for="(message, index) in details.conversation">
            <i18n class="subtitle c-divider"
              :key="`subtitle-${index}`"
              v-if="startedUnreadIndex === index">
              New messages
            </i18n>
            <message-notification
              :key="`notification-${index}`"
              v-if="message.from === 'notification'">
              {{message.text}}
            </message-notification>

            <component v-else
              v-bind="getMessageAt[index]"
              :key="`message-${index}`"/>
          </template>
          <message
            v-for="(message, index) in ephemeral.pendingMessages"
            :key="index"
            v-bind="getPendingAt[index]"
            @retry="retryMessage(index)"
          />

        <send-area :title="summary.title"
          @send="handleSendMessage"
          @heightUpdate="updateSendAreaHeight"
        />

    </template>

</template>

<template>

    <template v-if="summary.title">

        <template slot="title">
          <avatar :src="summary.picture" alt=""
            class="c-header-avatar"
            size="sm"
            hasMargin
          />

          {{summary.title}}
        </template>
        <template slot="actions">
          <button class="button is-icon">

          </button>
          <button class="button is-icon">

          </button>
          <menu-parent class="level-right">
            <menu-trigger class="is-icon">

            </menu-trigger>

            <menu-content class="c-actions-content">
              <list hasMargin>
                <menu-item tag="button" itemId="hash-1" icon="heart">
                  <i18n>Option 1</i18n>
                </menu-item>
                <menu-item tag="button" itemId="hash-2" icon="heart">
                  <i18n>Option 2</i18n>
                </menu-item>
                <menu-item tag="button" itemId="hash-3" icon="heart">
                  <i18n>Option 3</i18n>
                </menu-item>
              </list>
            </menu-content>
          </menu-parent>
        </template>

          <loading />

          <conversation-greetings />
          <template v-for="(message, index) in details.conversation">
            <i18n class="subtitle c-divider"
              :key="`subtitle-${index}`"
              v-if="startedUnreadIndex === index">
              New messages
            </i18n>
            <message-notification
              :key="`notification-${index}`"
              v-if="message.from === 'notification'">
              {{message.text}}
            </message-notification>

            <component v-else
              v-bind="getMessageAt(index)"
              :key="`message-${index}`"/>
          </template>
          <message
            v-for="(message, index) in ephemeral.pendingMessages"
            :key="index"
            v-bind="getPendingAt[index]"
            @retry="retryMessage(index)"
          />

        <send-area :title="summary.title"
          @send="handleSendMessage"
          @heightUpdate="updateSendAreaHeight"
        />

    </template>

</template>


change # of insights to 12

change # of insights to 12

<template>
  <d-container fluid class="main-content-container px-4">

Most Anomalous Insights Across Your Repos

        <d-row>

          <d-col v-for="(record, idx) in highest_frame" :key="idx" lg="4" md="4" sm="6" class="mb-4">

            <d-card v-if="idx < highest_frame.length" class="card-small card-post card-post--1">

                <spinner style="padding: 1rem 0 1rem 0; position: relative; transform: translateY(-50%);"></spinner>

                <d-badge pill :class="['card-post__category', 'bg-' + (color_mapping[highest[idx].ri_metric].theme || 'info') ]">{{ highest[idx].ri_metric }} ({{ highest[idx].ri_field }})</d-badge>
                <insight-chart style="" :data="insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric]" :url="highest[idx].repo_git" :color="color_mapping[highest[idx].ri_metric].hex || '#FFC107'"></insight-chart>

                    {{ getDirection(insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric]) }}

              <d-card-body v-if="loadedInsights">

                  {{ highest[idx].repo_git.substr(19) }}
                  <d-tooltip
                    :target="'#' + idx"
                    container=".shards-demo--example--tooltip-01"
                    placement="right"
                    offset="10">
                    Click here to see an overview of this repository's metrics
                  </d-tooltip>

This repository had a sharp {{ getPhrase(insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric]) }}

                <d-row>
                  <d-col cols="12" sm="5">
                    <d-row>
                      <d-col cols="12" sm="12">
                        {{ timeframes[highest[idx].repo_git] }}
                      </d-col>

                      <d-col cols="12" sm="12">
                        <d-button
                        theme="info" size="sm"
                        :id="'inspect' + idx"
                        @click="onInspectInsight(insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric][0])"
                        style="color: white !important"
                        class="d-flex btn-white ml-auto mr-auto ml-sm-auto mr-sm-0 mt-3 mt-sm-0">View Insight Details →</d-button>
                        <d-tooltip
                          :target="'#inspect' + idx"
                          container=".shards-demo--example--tooltip-01"
                          placement="right"
                          offset="20">
                          Click to see more about this insight.
                        </d-tooltip>
                      </d-col>
                    </d-row>
                  </d-col>

                  <d-col cols="12" sm="7" style="transform: translateX(-1rem) !important;">
                    <d-row>

                      <d-col cols="12" sm="12">
                        <d-button
                        :id="'ev' + idx"
                        size="sm"
                        @click="onGitRepo(insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric][0])"
                        style="color: white !important"
                        class="d-flex btn-white ml-auto mr-auto ml-sm-auto mr-sm-0 mt-3 mt-sm-0">Evolution →</d-button>
                        <d-tooltip
                          :target="'#ev' + idx"
                          container=".shards-demo--example--tooltip-01"
                          placement="right"
                          offset="20">
                          Click to see evolution metrics for this repo.
                        </d-tooltip>
                      </d-col>

                      <d-col cols="12" sm="12">
                        <d-button theme="secondary" :id="'ri' + idx" size="sm" @click="onRisk(insights[highest[idx].rg_name][highest[idx].repo_git][highest[idx].ri_metric][0])" style="color: white !important" class="d-flex btn-white ml-auto mr-auto ml-sm-auto mr-sm-0 mt-3 mt-sm-0">Risk →</d-button>
                        <d-tooltip
                          :target="'#ri' + idx"
                          container=".shards-demo--example--tooltip-01"
                          placement="right"
                          offset="20">
                          Click to see risk metrics for this repo.
                        </d-tooltip>
                      </d-col>
                    </d-row>
                  </d-col>
                </d-row>
              </d-card-body>
            </d-card>
          </d-col>
        </d-row>

  </d-container>
</template>


fixed missing `.vue` extension on import

<template>
    <input v-if="!static"
           :type="type"
           :value="value"
           :name="name"
           :id="_id"
           :disabled="disabled"
           ref="input"

           :is="textarea?'textarea':'input'"
           :class="['form-control',inputClass]"
           :rows="rows || rowsCount"

           :placeholder="placeholder"

           @input="onInput($event.target.value)"
           @change="onChange($event.target.value)"
           @keyup="onKeyUp($event)"
           @focus="$emit('focus')"
           @blur="$emit('blur')"
    />
    <b-form-input-static v-else
                         :id="_id"
                         :value="value"
                         :formatter="formatter"
    ></b-form-input-static>
</template>

<script>
    import formMixin from '../mixins/form';
    import bFormInputStatic from './form-input-static.vue';
    import generateId from '../mixins/generate-id';

    export default {
        mixins: [formMixin, generateId],
        components: {bFormInputStatic},
        computed: {
            rowsCount() {
                return (this.value || '').toString().split('\n').length;
            }
        },
        methods: {
            format(value) {
                if (this.formatter) {
                    const formattedValue = this.formatter(value);
                    if (formattedValue !== value) {
                        value = formattedValue;
                        this.$refs.input.value = formattedValue;
                    }
                }
                return value;
            },
            onInput(value) {
                if (!this.lazyFormatter) {
                    value = this.format(value);
                }
                this.$emit('input', value);
            },
            onChange(value) {
                value = this.format(value);
                this.$emit('input', value);
                this.$emit('change', value);
            },
            onKeyUp(e) {
                this.$emit('keyup', e);
            }
        },
        props: {
            value: {
                default: null
            },
            type: {
                type: String,
                default: 'text'
            },
            static: {
                type: Boolean,
                default: false
            },
            placeholder: {
                type: String,
                default: null
            },
            rows: {
                type: Number,
                default: null
            },
            textarea: {
                type: Boolean,
                default: false
            },
            formatter: {
                type: Function
            },
            lazyFormatter: {
                type: Boolean,
                default: false
            }
        }
    };

</script>

<template>
    <input v-if="!static"
           :type="type"
           :value="value"
           :name="name"
           :id="_id"
           :disabled="disabled"
           ref="input"

           :is="textarea?'textarea':'input'"
           :class="['form-control',inputClass]"
           :rows="rows || rowsCount"

           :placeholder="placeholder"

           @input="onInput($event.target.value)"
           @change="onChange($event.target.value)"
           @keyup="onKeyUp($event)"
           @focus="$emit('focus')"
           @blur="$emit('blur')"
    />
    <b-form-input-static v-else
                         :id="_id"
                         :value="value"
                         :formatter="formatter"
    ></b-form-input-static>
</template>

<script>
    import formMixin from '../mixins/form';
    import bFormInputStatic from './form-input-static';
    import generateId from '../mixins/generate-id';

    export default {
        mixins: [formMixin, generateId],
        components: {bFormInputStatic},
        computed: {
            rowsCount() {
                return (this.value || '').toString().split('\n').length;
            }
        },
        methods: {
            format(value) {
                if (this.formatter) {
                    const formattedValue = this.formatter(value);
                    if (formattedValue !== value) {
                        value = formattedValue;
                        this.$refs.input.value = formattedValue;
                    }
                }
                return value;
            },
            onInput(value) {
                if (!this.lazyFormatter) {
                    value = this.format(value);
                }
                this.$emit('input', value);
            },
            onChange(value) {
                value = this.format(value);
                this.$emit('input', value);
                this.$emit('change', value);
            },
            onKeyUp(e) {
                this.$emit('keyup', e);
            }
        },
        props: {
            value: {
                default: null
            },
            type: {
                type: String,
                default: 'text'
            },
            static: {
                type: Boolean,
                default: false
            },
            placeholder: {
                type: String,
                default: null
            },
            rows: {
                type: Number,
                default: null
            },
            textarea: {
                type: Boolean,
                default: false
            },
            formatter: {
                type: Function
            },
            lazyFormatter: {
                type: Boolean,
                default: false
            }
        }
    };

</script>


Add Jon's line-height back

Add Jon's line-height back

<template>
  <uw-card-property title="Meeting Time" :sr-only-title="!showRowHeading">

          <th v-if="section.hasEosDates" :id="`dates-${section.id}`">
            Meeting Date(s)

          <th :id="`days-${section.id}`">
            Meeting Day(s)

          <th :id="`time-${section.id}`">
            Meeting Time

          <th :id="`location-${section.id}`">
            Meeting Location

          <th v-if="section.showMtgType" :id="`type-${section.id}`">
            Meeting Type

          <td v-if="section.hasEosDates"
            :headers="`dates-${meeting.id}`"
            class="text-left p-0"
          >

              {{ formatEos(meeting) }}

          <td v-if="meeting.wont_meet"
            :headers="`days-${meeting.id}`"
            colspan="3" class="p-0"
          >
            Class does not meet

          <td v-else-if="meeting.days_tbd"
            :headers="`days-${meeting.id}`"
            colspan="3" class="p-0"
          >
            Days and times to be arranged

          <td v-else-if="meeting.no_meeting"
            :headers="`days-${meeting.id}`"
            colspan="3" class="p-0"
          >
            No classroom meeting: online learning

          <template v-else-if="meeting.start_time && meeting.end_time">
            <td :headers="`days-${meeting.id}`"
              class="p-0 text-left text-nowrap pr-3"
            >
              <uw-meeting-days :meeting="meeting" />

            <td :headers="`time-${meeting.id}`"
              class="p-0 text-left"
            >
              {{ meeting.start_time.format('h:mm A') }} –
              {{ meeting.end_time.format('h:mm A') }}

            <td :headers="`location-${meeting.id}`"
              class="p-0 text-left text-nowrap"
            >
              <uw-meeting-location :meeting="meeting" />

          </template>

          <td v-if="section.showMtgType"
            :headers="`type-${meeting.id}`"
            class="p-0 text-left"
          >
            <span v-if="meeting.displayType" :title="`${meeting.type}`"
                  :class="`px-1 border myuw-text-sm
                  text-uppercase text-c${section.color_id}`"
            >
              {{ shortenMtgType(meeting.type) }}

  </uw-card-property>
</template>


Fix datepicker disappear on click

Fix datepicker disappear on click

<template>

            <input class="SharpDate__input"
                   :placeholder="displayFormat"
                   :value="inputValue"
                   :disabled="readOnly"
                   @input="handleInput"
                   @blur="handleBlur"
                   @keydown.up.prevent="increase"
                   @keydown.down.prevent="decrease"
                   ref="input">
            <button class="SharpDate__clear-button" type="button" @click="clear()" ref="clearButton">
                <svg class="SharpDate__clear-button-icon"
                     aria-label="close" width="10" height="10" viewBox="0 0 10 10" fill-rule="evenodd">
                    <path d="M9.8 8.6L8.4 10 5 6.4 1.4 10 0 8.6 3.6 5 .1 1.4 1.5 0 5 3.6 8.6 0 10 1.4 6.4 5z"></path>
                </svg>
            </button>

        $refs.input" :show.sync="showPicker" container="sharp-app" triggers="focus" placement="bottom">

                <template v-if="hasDate">
                    <sharp-date-picker
                        class="SharpDate__date"
                        :language="language"
                        inline monday-first
                        :value="dateObject"
                        @selected="handleDateSelect"
                        ref="datepicker"
                    />
                </template>
                <template v-if="hasTime">
                    <sharp-time-picker
                        class="SharpDate__time"
                        :value="timeObject"
                        :active="showPicker"
                        :format="displayFormat"
                        :minute-interval="stepTime"
                        :min="minTime" :max="maxTime"
                        @change="handleTimeSelect"
                        ref="timepicker"
                    />
                </template>

</template>

<template>

            <input class="SharpDate__input"
                   :placeholder="displayFormat"
                   :value="inputValue"
                   :disabled="readOnly"
                   @input="handleInput"
                   @blur="handleBlur"
                   @focus="handleFocus"
                   @keydown.up.prevent="increase"
                   @keydown.down.prevent="decrease"
                   ref="input">
            <button class="SharpDate__clear-button" type="button" @click="clear()" ref="clearButton">
                <svg class="SharpDate__clear-button-icon"
                     aria-label="close" width="10" height="10" viewBox="0 0 10 10" fill-rule="evenodd">
                    <path d="M9.8 8.6L8.4 10 5 6.4 1.4 10 0 8.6 3.6 5 .1 1.4 1.5 0 5 3.6 8.6 0 10 1.4 6.4 5z"></path>
                </svg>
            </button>

        $refs.input" :show.sync="showPicker" container="sharp-app" triggers="" placement="bottom">

                <template v-if="hasDate">
                    <sharp-date-picker
                        class="SharpDate__date"
                        :language="language"
                        inline monday-first
                        :value="dateObject"
                        @selected="handleDateSelect"
                        ref="datepicker"
                    />
                </template>
                <template v-if="hasTime">
                    <sharp-time-picker
                        class="SharpDate__time"
                        :value="timeObject"
                        :active="showPicker"
                        :format="displayFormat"
                        :minute-interval="stepTime"
                        :min="minTime" :max="maxTime"
                        @change="handleTimeSelect"
                        ref="timepicker"
                    />
                </template>

</template>


Set * when layout is tablet properly

Set * when layout is tablet properly

<template>

{{title}}

{{ $t('QuotaSection.header.remaining') }}

{{ $t('QuotaSection.header.used') }}

            {{$t(`QuotaSection.header.total`)}} {{ $t(`QuotaSection.header.perMonth`) }}

      <slot></slot>

</template>


Minor UI changes

Minor UI changes


add list transition

add list transition

<template type="text/html">

            <svg class="player-control" @click="toggleState" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <circle class="player-progress-slot" cx="50%" cy="50%" r="48" stroke-width="2px"
                        stroke="rgba(255,255,255,.3)"></circle>
                <circle class="player-progress-fill" transform="rotate(-90,50 50)" stroke-linecap="round"
                        :stroke-dasharray="l"
                        :stroke-dashoffset="p" cx="50%" cy="50%" r="48" stroke-width="2px"
                        stroke="rgba(255,255,255,.8)"></circle>
                <circle class="player-progress-dot" v-show="state!=stateMap.stop" :cx="cx" :cy="cy" r="3"></circle>
                <circle class="player-progress-dotbg" v-show="state!=stateMap.stop" :cx="cx" :cy="cy" r="6"></circle>
                <polygon class="player-control-play" v-show="state<=0" points="42,36 64,50 42,64"></polygon>
                <g class="player-control-pause" v-show="state>0">
                    <rect x="39" y="38" width="6" height="24"></rect>
                    <rect x="55" y="38" width="6" height="24"></rect>
                </g>
            </svg>
            <canvas ref="frequency" width="300px" height="200px"></canvas>
            <canvas ref="frequency_shadow" width="300px" height="200px"></canvas>

{{audioInfo.name | rmExt}}

                    <canvas ref="curve" width="300px" height="30px"></canvas>

                <canvas ref="curve_full" width="300px" height="30px"></canvas>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path fill-rule="evenodd" clip-rule="evenodd"
                              d="M1.2 5.2c-.6 0-1.2.4-1.2.9v3.7c0 .6.6 1 1.2 1H3l6.1 4V1.1L3 5.1H1.2zm10.8-3l-.4 1.2c1.8.6 3.3 2.5 3.3 4.6 0 2.1-1.4 4-3.3 4.7l.4 1.2c2.3-.9 4-3.2 4-5.8 0-2.8-1.7-5.1-4-5.9zM13.7 8c0-1.5-1-2.8-2.5-3.1l-.4 1.2c1 .1 1.8.9 1.8 1.9s-.8 1.8-1.7 1.8l.4 1.2c1.3-.2 2.4-1.5 2.4-3z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M4.3,5C3.7,5,3,5.4,3,6V10c0,0.7,0.7,1.1,1.3,1.1h2l6.7,4.4v-15L6.3,4.9C6.3,4.9,4.3,5,4.3,5z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M14.9 1.6H1.1C.5 1.6 0 2.1 0 2.7v8.5c0 .6.5 1.1 1.1 1.1h2.7c.3 0 .5-.4.5-.5v-1.1c0-.1-.2-.5-.5-.5h-1c-.4 0-.6-.3-.6-.6V4.4c0-.4.3-.6.6-.6h10.4c.4 0 .6.3.6.6v5.1c0 .4-.3.6-.6.6H9.6V8l-3.7 3.2 3.7 3.2v-2.1h5.3c.6 0 1.1-.5 1.1-1.1V2.7c0-.6-.5-1.1-1.1-1.1z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M.5 5.3h3.2l1.1 1.6L6.1 5l-1-1.5c-.3-.3-.7-.3-.9-.3H.5c-.3 0-.5.2-.5.5v1.1c0 .3.2.5.5.5zm11.8 5.4H10L8.9 9.1 7.6 11l1 1.4c.3.4.5.4 1.1.4h2.7v2.1l3.7-3.2-3.7-3.2v2.2zm0-5.4v2.1L16 4.3l-3.7-3.2v2.1H9.6c-.9 0-.9.2-1 .3l-4.9 7.2H.5c-.3 0-.5.2-.5.5v1.1c0 .3.2.5.5.5h3.7c.2 0 .6 0 .7-.2l5-7.2h2.4z"/>
                    </svg>

                    <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                        <path d="M133.31 296.552h757.207c19.782 0 35.951-16.169 35.951-35.95 0-19.782-15.997-35.952-35.95-35.952H133.31c-19.782 0-35.951 16.17-35.951 35.951 0 19.782 16.17 35.951 35.95 35.951zM890.517 476.135H133.311c-19.782 0-35.951 16.17-35.951 35.951 0 19.782 16.17 35.951 35.95 35.951h757.207c19.782 0 35.951-16.17 35.951-35.951 0-19.782-16.17-35.95-35.95-35.95zM890.517 727.448H133.311c-19.782 0-35.951 15.997-35.951 35.95s16.17 35.952 35.95 35.952h757.207c19.782 0 35.951-15.998 35.951-35.951s-16.17-35.951-35.95-35.951z"/>
                    </svg>

        <transition name="fade">

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M14.7,7H9V1.3C9,1.2,8.8,1,8.5,1h-1C7.3,1,7,1.2,7,1.3V7H1.3C1.2,7,1,7.2,1,7.5v1C1,8.8,1.2,9,1.3,9H7v5.5
	c0,0.2,0.3,0.3,0.6,0.4h1C8.8,15,9,14.8,9,14.7V9h5.6C14.8,9,15,8.8,15,8.5V7.5C15,7.2,14.8,7,14.7,7z"/>
                    </svg>
                    <input multiple type="file" @change="addAudio">

                    <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                        <path d="M890.335 330.911c-12.576-12.416-32.8-12.353-45.248.193L517.248 661.95 184.832 332.513c-12.576-12.448-32.8-12.353-45.28.192-12.448 12.577-12.354 32.832.192 45.281l353.311 350.112c.544.544 1.248.673 1.793 1.184.127.127.16.287.287.416a31.972 31.972 0 0 0 22.528 9.28c8.224 0 16.48-3.168 22.72-9.47l350.112-353.313c12.48-12.58 12.386-32.835-.16-45.284z"/>
                    </svg>

{{audio.name | rmExt}}

{{playProgressRate * audioInfo.duration | toMinute}} / {{audio.duration | toMinute}}

        </transition>

</template>

<template type="text/html">

            <svg class="player-control" @click="toggleState" xmlns="http://www.w3.org/2000/svg" version="1.1">
                <circle class="player-progress-slot" cx="50%" cy="50%" r="48" stroke-width="2px"
                        stroke="rgba(255,255,255,.3)"></circle>
                <circle class="player-progress-fill" transform="rotate(-90,50 50)" stroke-linecap="round"
                        :stroke-dasharray="l"
                        :stroke-dashoffset="p" cx="50%" cy="50%" r="48" stroke-width="2px"
                        stroke="rgba(255,255,255,.8)"></circle>
                <circle class="player-progress-dot" v-show="state!=stateMap.stop" :cx="cx" :cy="cy" r="3"></circle>
                <circle class="player-progress-dotbg" v-show="state!=stateMap.stop" :cx="cx" :cy="cy" r="6"></circle>
                <polygon class="player-control-play" v-show="state<=0" points="42,36 64,50 42,64"></polygon>
                <g class="player-control-pause" v-show="state>0">
                    <rect x="39" y="38" width="6" height="24"></rect>
                    <rect x="55" y="38" width="6" height="24"></rect>
                </g>
            </svg>
            <canvas  ref="frequency" width="300px" height="200px"></canvas>
            <canvas   ref="frequency_shadow" width="300px" height="200px"></canvas>

{{audioInfo.name | rmExt}}

                    <canvas ref="curve" width="300px" height="30px"></canvas>

                <canvas ref="curve_full" width="300px" height="30px"></canvas>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path fill-rule="evenodd" clip-rule="evenodd"
                              d="M1.2 5.2c-.6 0-1.2.4-1.2.9v3.7c0 .6.6 1 1.2 1H3l6.1 4V1.1L3 5.1H1.2zm10.8-3l-.4 1.2c1.8.6 3.3 2.5 3.3 4.6 0 2.1-1.4 4-3.3 4.7l.4 1.2c2.3-.9 4-3.2 4-5.8 0-2.8-1.7-5.1-4-5.9zM13.7 8c0-1.5-1-2.8-2.5-3.1l-.4 1.2c1 .1 1.8.9 1.8 1.9s-.8 1.8-1.7 1.8l.4 1.2c1.3-.2 2.4-1.5 2.4-3z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M4.3,5C3.7,5,3,5.4,3,6V10c0,0.7,0.7,1.1,1.3,1.1h2l6.7,4.4v-15L6.3,4.9C6.3,4.9,4.3,5,4.3,5z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M14.9 1.6H1.1C.5 1.6 0 2.1 0 2.7v8.5c0 .6.5 1.1 1.1 1.1h2.7c.3 0 .5-.4.5-.5v-1.1c0-.1-.2-.5-.5-.5h-1c-.4 0-.6-.3-.6-.6V4.4c0-.4.3-.6.6-.6h10.4c.4 0 .6.3.6.6v5.1c0 .4-.3.6-.6.6H9.6V8l-3.7 3.2 3.7 3.2v-2.1h5.3c.6 0 1.1-.5 1.1-1.1V2.7c0-.6-.5-1.1-1.1-1.1z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M.5 5.3h3.2l1.1 1.6L6.1 5l-1-1.5c-.3-.3-.7-.3-.9-.3H.5c-.3 0-.5.2-.5.5v1.1c0 .3.2.5.5.5zm11.8 5.4H10L8.9 9.1 7.6 11l1 1.4c.3.4.5.4 1.1.4h2.7v2.1l3.7-3.2-3.7-3.2v2.2zm0-5.4v2.1L16 4.3l-3.7-3.2v2.1H9.6c-.9 0-.9.2-1 .3l-4.9 7.2H.5c-.3 0-.5.2-.5.5v1.1c0 .3.2.5.5.5h3.7c.2 0 .6 0 .7-.2l5-7.2h2.4z"/>
                    </svg>

                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
                        <path d="M14.7,7H9V1.3C9,1.2,8.8,1,8.5,1h-1C7.3,1,7,1.2,7,1.3V7H1.3C1.2,7,1,7.2,1,7.5v1C1,8.8,1.2,9,1.3,9H7v5.5
	c0,0.2,0.3,0.3,0.6,0.4h1C8.8,15,9,14.8,9,14.7V9h5.6C14.8,9,15,8.8,15,8.5V7.5C15,7.2,14.8,7,14.7,7z"/>
                    </svg>
                    <input multiple type="file" @change="addAudio">

{{audio.name | rmExt}}

{{playProgressRate * audioInfo.duration | toMinute}} / {{audio.duration | toMinute}}

</template>


Stop chat loader after error

Stop chat loader after error


update welcome homepage

update welcome homepage

<template>

                                                Welcome to {{site_name}}

                                                powered by Rets Rabbit

This is an open source, browser based, API explorer for testing and evaluating real estate API servers that adhere to the RESO Web API standard.

Click the button below to add your RESO Web API server or use our default demo server to check out the explorer.

                                        <router-link to="/servers" class="waves-effect waves-light cyan lighten-1 btn">Go To Servers</router-link>

Disclaimer: This tool is not affiliated with the Real Estate Standards Organization (RESO). The source code for this tool can be found here.

                                    Upcoming Features

                                    Polygon Searching
                                    Multi Polygon Searching

</template>

<template>

                                                Welcome to {{site_name}}

                                                powered by Rets Rabbit

Designed by developers. For developers.

                                        <router-link to="/servers" class="waves-effect waves-light cyan lighten-1 btn">Go To Servers</router-link>

                                    Upcoming Features

                                    Polygon Searching
                                    Multi Polygon Searching

</template>


Update List.vue

Update List.vue

<template>

    <template v-if="mold === 'thumbnail'" v-for="item in items">
      <router-link
        class="thumbnail"
        :to="{name: 'DetailView', params: { id: item.id }}">

{{item.title}}

{{item.content | subStr}}

          {{item.category_name}}

            本活动来自栏目 {{item.subcategory_name}}

      </router-link>
    </template>
    <template v-if="mold === 'basic'">

{{item.title}}

{{item.comments}}

    </template>

</template>


Delete console

Delete console

<script>
  export default {
    beforeDestroy: function () {
      var self = this;
      if (!(self.virtual && self.virtualInit && self.f7VirtualList)) return;
      if (self.f7VirtualList.destroy) self.f7VirtualList.destroy();
    },
    watch: {
      virtualItems: function () {
        // Items Updated
        var self = this;
        if (!(self.virtual && self.virtualInit && self.f7VirtualList)) return;
        self.f7VirtualList.replaceAllItems(self.virtualItems);
      },
    },
    render: function (c) {
      var blockEl, blockChildren;
      var self = this;

      blockChildren = self.grouped ? self.$slots.default : c('ul', {}, self.$slots.default)
      var outOfList = [], ulSlots = [];
      if (self.$slots.default) {
        for (var i = 0; i < self.$slots.default.length; i++) {
          var tag = self.$slots.default[i].tag;
          if (tag && !(tag == 'li' || tag.indexOf('list-item')>=0 || tag.indexOf('list-button')>=0)) {
            outOfList.push(self.$slots.default[i]);
          }
          else {
            ulSlots.push(self.$slots.default[i]);
          }
        }
      }
      blockEl = c(
        self.form ? 'form' : 'div',
        {
          staticClass: 'list-block',
          'class': {
            'inset': self.inset,
            'tablet-inset': self.tabletInset,
            'media-list': self.mediaList,
            'sortable': self.sortable,
            'accordion-list': self.accordion,
            'contacts-block': self.contacts,
            'virtual-list': self.virtual,
            'tab': self.tab,
            'active': self.active,
            'no-hairlines': self.noHairlines,
            'no-hairlines-between': self.noHairlinesBetween,
            'store-data': self.storeData
          },
          on: {
            'sortable:open': self.onSortableOpen,
            'sortable:close': self.onSortableClose,
            'sortable:sort': self.onSortableSort,
            'tab:show': self.onTabShow,
            'tab:hide': self.onTabHide
          }
        },
        [
          ulSlots.length > 0 ? [c('ul', {}, ulSlots), outOfList] : outOfList
        ]
      );
      return blockEl;
    },
    props: {
      'inset': Boolean,
      'tablet-inset': Boolean,
      'media-list': Boolean,
      'grouped': Boolean,
      'sortable': Boolean,
      'label': String,
      'accordion': Boolean,
      'contacts': Boolean,

      'no-hairlines': Boolean,
      'no-hairlines-between': Boolean,

      // Tab
      'tab': Boolean,
      'active': Boolean,

      // Form
      'form': Boolean,
      'store-data': Boolean,

      // Virtual List
      'virtual': Boolean,
      'virtual-init': {
        type: Boolean,
        default: true
      },
      'virtual-items': [Array, Object],
      'virtual-height': [Number, Function],
      'virtual-rows-before': Number,
      'virtual-rows-after': Number,
      'virtual-cols': {
        type: Number,
        default: 1
      },
      'virtual-cache': {
        type: Boolean,
        default: true
      },
      'virtual-filtered-only': {
        type: Boolean,
        default: false
      },
      'virtual-search-by-item': Function,
      'virtual-search-all': Function,
      'virtual-render-item': Function,
      'virtual-empty-template': String,
      'virtual-render-external': Function,
    },
    methods: {
      onSortableOpen: function (event) {
        this.$emit('sortable:open', event)
      },
      onSortableClose: function (event) {
        this.$emit('sortable:close', event)
      },
      onSortableSort: function (event) {
        this.$emit('sortable:sort', event, event.detail)
      },
      onTabShow: function (e) {
        this.$emit('tab:show', e);
      },
      onTabHide: function (e) {
        this.$emit('tab:hide', e);
      },
      onF7Init: function (f7) {
        var self = this;
        // Init Virtual List
        if (!(self.virtual && self.virtualInit)) return;
        var $$ = self.$$;
        var $el = $$(self.$el);
        var templateScript = $el.find('script');
        var template = templateScript.html();
        if(!template && templateScript.length > 0){
          template = templateScript[0].outerHTML;
          template = /\<script type="text\/template7"\>(.*)<\/script>/.exec(template)[1];
        }
        if (!template && !self.virtualRenderItem && !self.virtualRenderExternal) return;
        if (template) template = self.$t7.compile(template);

        self.f7VirtualList = f7.virtualList(self.$el, {
          items: self.virtualItems || [],
          template: template,
          height: self.virtualHeight || undefined,
          cols: self.virtualCols,
          rowsBefore: self.virtualRowsBefore || undefined,
          rowsAfter: self.virtualRowsAfter || undefined,
          showFilteredItemsOnly: self.virtualFilteredOnly,
          searchByItem: self.virtualSearchByItem,
          searchAll: self.virtualSearchAll,
          renderItem: self.virtualRenderItem,
          renderExternal: self.virtualRenderExternal,
          emptyTemplate: self.virtualEmptyTemplate,
          onItemBeforeInsert: function (list, item) {
            self.$emit('virtual:itembeforeinsert', list, item);
          },
          onBeforeClear: function (list, fragment) {
            self.$emit('virtual:beforeclear', list, fragment);
          },
          onItemsBeforeInsert: function (list, fragment) {
            self.$emit('virtual:itemsbeforeinsert', list, fragment);
          },
          onItemsAfterInsert: function (list, fragment) {
            self.$emit('virtual:itemsafterinsert', list, fragment);
          },
        })
      }
    }
  }
</script>

<script>
  export default {
    beforeDestroy: function () {
      var self = this;
      if (!(self.virtual && self.virtualInit && self.f7VirtualList)) return;
      if (self.f7VirtualList.destroy) self.f7VirtualList.destroy();
    },
    watch: {
      virtualItems: function () {
        // Items Updated
        var self = this;
        if (!(self.virtual && self.virtualInit && self.f7VirtualList)) return;
        self.f7VirtualList.replaceAllItems(self.virtualItems);
      },
    },
    render: function (c) {
      var blockEl, blockChildren;
      var self = this;

      blockChildren = self.grouped ? self.$slots.default : c('ul', {}, self.$slots.default)
      var outOfList = [], ulSlots = [];
      if (self.$slots.default) {
        for (var i = 0; i < self.$slots.default.length; i++) {
          var tag = self.$slots.default[i].tag;
          if (tag && !(tag == 'li' || tag.indexOf('list-item')>=0 || tag.indexOf('list-button')>=0)) {
            outOfList.push(self.$slots.default[i]);
          }
          else {
            ulSlots.push(self.$slots.default[i]);
          }
        }
      }
      blockEl = c(
        self.form ? 'form' : 'div',
        {
          staticClass: 'list-block',
          'class': {
            'inset': self.inset,
            'tablet-inset': self.tabletInset,
            'media-list': self.mediaList,
            'sortable': self.sortable,
            'accordion-list': self.accordion,
            'contacts-block': self.contacts,
            'virtual-list': self.virtual,
            'tab': self.tab,
            'active': self.active,
            'no-hairlines': self.noHairlines,
            'no-hairlines-between': self.noHairlinesBetween,
            'store-data': self.storeData
          },
          on: {
            'sortable:open': self.onSortableOpen,
            'sortable:close': self.onSortableClose,
            'sortable:sort': self.onSortableSort,
            'tab:show': self.onTabShow,
            'tab:hide': self.onTabHide
          }
        },
        [
          ulSlots.length > 0 ? [c('ul', {}, ulSlots), outOfList] : outOfList
        ]
      );
      return blockEl;
    },
    props: {
      'inset': Boolean,
      'tablet-inset': Boolean,
      'media-list': Boolean,
      'grouped': Boolean,
      'sortable': Boolean,
      'label': String,
      'accordion': Boolean,
      'contacts': Boolean,

      'no-hairlines': Boolean,
      'no-hairlines-between': Boolean,

      // Tab
      'tab': Boolean,
      'active': Boolean,

      // Form
      'form': Boolean,
      'store-data': Boolean,

      // Virtual List
      'virtual': Boolean,
      'virtual-init': {
        type: Boolean,
        default: true
      },
      'virtual-items': [Array, Object],
      'virtual-height': [Number, Function],
      'virtual-rows-before': Number,
      'virtual-rows-after': Number,
      'virtual-cols': {
        type: Number,
        default: 1
      },
      'virtual-cache': {
        type: Boolean,
        default: true
      },
      'virtual-filtered-only': {
        type: Boolean,
        default: false
      },
      'virtual-search-by-item': Function,
      'virtual-search-all': Function,
      'virtual-render-item': Function,
      'virtual-empty-template': String,
      'virtual-render-external': Function,
    },
    methods: {
      onSortableOpen: function (event) {
        this.$emit('sortable:open', event)
      },
      onSortableClose: function (event) {
        this.$emit('sortable:close', event)
      },
      onSortableSort: function (event) {
        this.$emit('sortable:sort', event, event.detail)
      },
      onTabShow: function (e) {
        this.$emit('tab:show', e);
      },
      onTabHide: function (e) {
        this.$emit('tab:hide', e);
      },
      onF7Init: function (f7) {
        var self = this;
        // Init Virtual List
        if (!(self.virtual && self.virtualInit)) return;
        var $$ = self.$$;
        var $el = $$(self.$el);
        var templateScript = $el.find('script');
        var template = templateScript.html();
        if(!template && templateScript.length > 0){
          template = templateScript[0].outerHTML;
          template = /\<script type="text\/template7"\>(.*)<\/script>/.exec(template)[1];
        }
        console.log(self.virtualRenderExternal)
        if (!template && !self.virtualRenderItem && !self.virtualRenderExternal) return;
        console.log(2)
        if (template) template = self.$t7.compile(template);

        self.f7VirtualList = f7.virtualList(self.$el, {
          items: self.virtualItems || [],
          template: template,
          height: self.virtualHeight || undefined,
          cols: self.virtualCols,
          rowsBefore: self.virtualRowsBefore || undefined,
          rowsAfter: self.virtualRowsAfter || undefined,
          showFilteredItemsOnly: self.virtualFilteredOnly,
          searchByItem: self.virtualSearchByItem,
          searchAll: self.virtualSearchAll,
          renderItem: self.virtualRenderItem,
          renderExternal: self.virtualRenderExternal,
          emptyTemplate: self.virtualEmptyTemplate,
          onItemBeforeInsert: function (list, item) {
            self.$emit('virtual:itembeforeinsert', list, item);
          },
          onBeforeClear: function (list, fragment) {
            self.$emit('virtual:beforeclear', list, fragment);
          },
          onItemsBeforeInsert: function (list, fragment) {
            self.$emit('virtual:itemsbeforeinsert', list, fragment);
          },
          onItemsAfterInsert: function (list, fragment) {
            self.$emit('virtual:itemsafterinsert', list, fragment);
          },
        })
      }
    }
  }
</script>


Fix prop type

Fix prop type

<script>
  export default {
    render: function (c) {
      var pageEl, pageContentEl, ptrEl, infiniteEl, fixedList = [], staticList = [];
      var self = this;

      if (self.pullToRefresh && (self.ptrLayer && self.pullToRefreshLayer)) {
        ptrEl = c('div', {class: {'pull-to-refresh-layer': true}} ,[
          c('div', {class: {'preloader': true}}),
          c('div', {class: {'pull-to-refresh-arrow': true}})
        ]);
      }
      if ((self.infiniteScroll || self.infiniteScroll === '') && self.infiniteScrollPreloader) {
        infiniteEl = c('div', {class: {'infinite-scroll-preloader': true}} ,[
          c('div', {class: {'preloader': true}})
        ]);
      }

      var fixedTags = ('navbar toolbar tabbar subnavbar searchbar messagebar fab speed-dial floating-button').split(' ');

      var tag, child, withSubnavbar, withMessages, withSearchbar;
      if (self.$slots.default) {
        for (var i = 0; i < self.$slots.default.length; i++) {
          child = self.$slots.default[i];
          tag = child.tag;
          if (!tag) {
            staticList.push(child);
            continue;
          }
          var isFixed = false;
          if (tag.indexOf('messages') >= 0) withMessages = true;
          if (tag.indexOf('subnavbar') >= 0) withSubnavbar = true;
          if (tag.indexOf('searchbar') >= 0) withSearchbar = true;
          for (var j = 0; j < fixedTags.length; j++) {
            if (tag.indexOf(fixedTags[j]) >= 0) {
              isFixed = true;
            }
          }
          if (isFixed) fixedList.push(child);
          else staticList.push(child);
        }
      }

      if (fixedList.length > 0 && withSearchbar) {
        fixedList.push(c('div', {class:{'searchbar-overlay': true}}));
      }
      if (withMessages) self.classesObjectPageContent['messages-content'] = true;
      if (!self.noPageContent) {
        pageContentEl = c('div', {
          staticClass: 'page-content',
          class: self.classesObjectPageContent,
          attrs: {
            'data-ptr-distance': self.pullToRefreshDistance || self.ptrDistance,
            'data-distance': self.infiniteScrollDistance
          },
          on: {
            'ptr:pullstart': self.onPtrPullstart,
            'ptr:pullmove': self.onPtrPullmove,
            'ptr:pullend': self.onPtrPullend,
            'ptr:refresh': self.onPtrRefresh,
            'ptr:done': self.onPtrRefreshdone,
            'infinite': self.onInfinite
          },
        }, (self.infiniteScroll === 'top' ? [ptrEl, infiniteEl, self.$slots.static, staticList] : [ptrEl, self.$slots.static, staticList, infiniteEl]))
      }
      else {
        pageContentEl = [self.$slots.default];
      }
      fixedList.push(self.$slots.fixed);

      if (withSubnavbar) self.classesObjectPage['with-subnavbar'] = true;
      pageEl = c('div', {
        staticClass: 'page',
        class: self.classesObjectPage,
        attrs: {
          'data-page': self.name
        },
        on: {
          'page:beforeinit': self.onPageBeforeInit,
          'page:init': self.onPageInit,
          'page:reinit': self.onPageReinit,
          'page:beforeanimation': self.onPageBeforeAnimation,
          'page:afteranimation': self.onPageAfterAnimation,
          'page:beforeremove': self.onPageBeforeRemove,
          'page:back': self.onPageBack,
          'page:afterback': self.onPageAfterBack
        }
      }, [fixedList, pageContentEl]);

      return pageEl;

    },
    props: {
      'name': String,
      'cached': Boolean,
      'navbar-fixed': Boolean,
      'navbar-through': Boolean,
      'toolbar-fixed': Boolean,
      'toolbar-through': Boolean,
      'tabbar-fixed': Boolean,
      'tabbar-through': Boolean,
      'tabbar-labels-fixed': Boolean,
      'tabbar-labels-through': Boolean,
      'with-subnavbar': Boolean,
      'subnavbar': Boolean,
      'no-navbar': Boolean,
      'no-toolbar': Boolean,
      'no-tabbar': Boolean,
      'pull-to-refresh': Boolean,
      'pull-to-refresh-distance': Number,
      'ptr-distance': Number,
      'pull-to-refresh-layer': {
        type: Boolean,
        default: true
      },
      'ptr-layer': {
        type: Boolean,
        default: true
      },
      'infinite-scroll': [Boolean, String],
      'infinite-scroll-distance': Number,
      'infinite-scroll-preloader': {
        type: Boolean,
        default: true
      },
      'hide-bars-on-scroll': Boolean,
      'hide-navbar-on-scroll': Boolean,
      'hide-toolbar-on-scroll': Boolean,
      'hide-tabbar-on-scroll': Boolean,
      'messages': Boolean,
      'tabs': Boolean,
      'no-page-content': Boolean,
      'login-screen': Boolean,
      'theme': String,
      'layout': String,
      'no-swipeback': Boolean
    },
    computed: {
      classesObjectPage: function () {
        var co = {
          'cached': this.cached,
          'navbar-fixed': this.navbarFixed || this.navbarThrough && this.$theme.material,
          'navbar-through': this.navbarThrough,
          'toolbar-fixed': this.toolbarFixed,
          'toolbar-through': this.toolbarThrough,
          'tabbar-fixed': this.tabbarFixed,
          'tabbar-through': this.tabbarThrough,
          'tabbar-labels-fixed': this.tabbarLabelsFixed,
          'tabbar-labels-through': this.tabbarLabesThrough,
          'with-subnavbar': this.subnavbar || this.withSubnavbar,
          'no-navbar': this.noNavbar,
          'no-toolbar': this.noToolbar,
          'no-tabbar': this.noTabbar,
          'tabs': this.tabs,
          'no-swipeback': this.noSwipeBack
        }
        if (this.theme) co['theme-' + this.theme] = true;
        if (this.layout) co['layout-' + this.layout] = true;
        return co;
      },
      classesObjectPageContent: function () {
        return {
          'pull-to-refresh-content': this.pullToRefresh,
          'infinite-scroll': this.infiniteScroll || this.infiniteScroll === '',
          'infinite-scroll-top': this.infiniteScroll === 'top',
          'hide-bars-on-scroll': this.hideBarsOnScroll,
          'hide-navbar-on-scroll': this.hideNavbarOnScroll,
          'hide-toolbar-on-scroll': this.hideToolbarOnScroll,
          'hide-tabbar-on-scroll': this.hideTabbarOnScroll,
          'messages-content': this.messages,
          'login-screen-content': this.loginScreen
        }
      }
    },
    methods: {
      onPtrPullstart: function (event) {
        this.$emit('ptr:pullstart', event);
      },
      onPtrPullmove: function (event) {
        this.$emit('ptr:pullmove', event);
      },
      onPtrPullend: function (event) {
        this.$emit('ptr:pullend', event);
      },
      onPtrRefresh: function (event) {
        this.$emit('ptr:refresh', event, event.detail.done);
      },
      onPtrRefreshdone: function (event) {
        this.$emit('ptr:done', event);
      },
      onInfinite: function (event) {
        this.$emit('infinite', event);
      },
      onPageBeforeInit: function (event) {
        this.f7PageData = event.detail.page;
        this.$emit('page:beforeinit', event, event.detail.page);
      },
      onPageInit: function (event) {
        this.$emit('page:init', event, event.detail.page);
      },
      onPageReinit: function (event) {
        this.$emit('page:reinit', event, event.detail.page);
      },
      onPageBeforeAnimation: function (event) {
        this.$emit('page:beforeanimation', event, event.detail.page);
      },
      onPageAfterAnimation: function (event) {
        this.$emit('page:afteranimation', event, event.detail.page);
      },
      onPageBeforeRemove: function (event) {
        this.$emit('page:beforeremove', event, event.detail.page);
      },
      onPageBack: function (event) {
        this.$emit('page:back', event, event.detail.page);
      },
      onPageAfterBack: function (event) {
        this.$emit('page:afterback', event, event.detail.page);
      }
    }
  }
</script>

<script>
  export default {
    render: function (c) {
      var pageEl, pageContentEl, ptrEl, infiniteEl, fixedList = [], staticList = [];
      var self = this;

      if (self.pullToRefresh && (self.ptrLayer && self.pullToRefreshLayer)) {
        ptrEl = c('div', {class: {'pull-to-refresh-layer': true}} ,[
          c('div', {class: {'preloader': true}}),
          c('div', {class: {'pull-to-refresh-arrow': true}})
        ]);
      }
      if (self.infiniteScroll && self.infiniteScrollPreloader) {
        infiniteEl = c('div', {class: {'infinite-scroll-preloader': true}} ,[
          c('div', {class: {'preloader': true}})
        ]);
      }

      var fixedTags = ('navbar toolbar tabbar subnavbar searchbar messagebar fab speed-dial floating-button').split(' ');

      var tag, child, withSubnavbar, withMessages, withSearchbar;
      if (self.$slots.default) {
        for (var i = 0; i < self.$slots.default.length; i++) {
          child = self.$slots.default[i];
          tag = child.tag;
          if (!tag) {
            staticList.push(child);
            continue;
          }
          var isFixed = false;
          if (tag.indexOf('messages') >= 0) withMessages = true;
          if (tag.indexOf('subnavbar') >= 0) withSubnavbar = true;
          if (tag.indexOf('searchbar') >= 0) withSearchbar = true;
          for (var j = 0; j < fixedTags.length; j++) {
            if (tag.indexOf(fixedTags[j]) >= 0) {
              isFixed = true;
            }
          }
          if (isFixed) fixedList.push(child);
          else staticList.push(child);
        }
      }

      if (fixedList.length > 0 && withSearchbar) {
        fixedList.push(c('div', {class:{'searchbar-overlay': true}}));
      }
      if (withMessages) self.classesObjectPageContent['messages-content'] = true;
      if (!self.noPageContent) {
        pageContentEl = c('div', {
          staticClass: 'page-content',
          class: self.classesObjectPageContent,
          attrs: {
            'data-ptr-distance': self.pullToRefreshDistance || self.ptrDistance,
            'data-distance': self.infiniteScrollDistance
          },
          on: {
            'ptr:pullstart': self.onPtrPullstart,
            'ptr:pullmove': self.onPtrPullmove,
            'ptr:pullend': self.onPtrPullend,
            'ptr:refresh': self.onPtrRefresh,
            'ptr:done': self.onPtrRefreshdone,
            'infinite': self.onInfinite
          },
        }, (self.infiniteScroll === 'top' ? [ptrEl, infiniteEl, self.$slots.static, staticList] : [ptrEl, self.$slots.static, staticList, infiniteEl]))
      }
      else {
        pageContentEl = [self.$slots.default];
      }
      fixedList.push(self.$slots.fixed);

      if (withSubnavbar) self.classesObjectPage['with-subnavbar'] = true;
      pageEl = c('div', {
        staticClass: 'page',
        class: self.classesObjectPage,
        attrs: {
          'data-page': self.name
        },
        on: {
          'page:beforeinit': self.onPageBeforeInit,
          'page:init': self.onPageInit,
          'page:reinit': self.onPageReinit,
          'page:beforeanimation': self.onPageBeforeAnimation,
          'page:afteranimation': self.onPageAfterAnimation,
          'page:beforeremove': self.onPageBeforeRemove,
          'page:back': self.onPageBack,
          'page:afterback': self.onPageAfterBack
        }
      }, [fixedList, pageContentEl]);

      return pageEl;

    },
    props: {
      'name': String,
      'cached': Boolean,
      'navbar-fixed': Boolean,
      'navbar-through': Boolean,
      'toolbar-fixed': Boolean,
      'toolbar-through': Boolean,
      'tabbar-fixed': Boolean,
      'tabbar-through': Boolean,
      'tabbar-labels-fixed': Boolean,
      'tabbar-labels-through': Boolean,
      'with-subnavbar': Boolean,
      'subnavbar': Boolean,
      'no-navbar': Boolean,
      'no-toolbar': Boolean,
      'no-tabbar': Boolean,
      'pull-to-refresh': Boolean,
      'pull-to-refresh-distance': Number,
      'ptr-distance': Number,
      'pull-to-refresh-layer': {
        type: Boolean,
        default: true
      },
      'ptr-layer': {
        type: Boolean,
        default: true
      },
      'infinite-scroll': [Boolean, String],
      'infinite-scroll-distance': Number,
      'infinite-scroll-preloader': {
        type: Boolean,
        default: true
      },
      'hide-bars-on-scroll': Boolean,
      'hide-navbar-on-scroll': Boolean,
      'hide-toolbar-on-scroll': Boolean,
      'hide-tabbar-on-scroll': Boolean,
      'messages': Boolean,
      'tabs': Boolean,
      'no-page-content': Boolean,
      'login-screen': Boolean,
      'theme': String,
      'layout': String,
      'no-swipeback': Boolean
    },
    computed: {
      classesObjectPage: function () {
        var co = {
          'cached': this.cached,
          'navbar-fixed': this.navbarFixed || this.navbarThrough && this.$theme.material,
          'navbar-through': this.navbarThrough,
          'toolbar-fixed': this.toolbarFixed,
          'toolbar-through': this.toolbarThrough,
          'tabbar-fixed': this.tabbarFixed,
          'tabbar-through': this.tabbarThrough,
          'tabbar-labels-fixed': this.tabbarLabelsFixed,
          'tabbar-labels-through': this.tabbarLabesThrough,
          'with-subnavbar': this.subnavbar || this.withSubnavbar,
          'no-navbar': this.noNavbar,
          'no-toolbar': this.noToolbar,
          'no-tabbar': this.noTabbar,
          'tabs': this.tabs,
          'no-swipeback': this.noSwipeBack
        }
        if (this.theme) co['theme-' + this.theme] = true;
        if (this.layout) co['layout-' + this.layout] = true;
        return co;
      },
      classesObjectPageContent: function () {
        return {
          'pull-to-refresh-content': this.pullToRefresh,
          'infinite-scroll': this.infiniteScroll,
          'infinite-scroll-top': this.infiniteScroll === 'top',
          'hide-bars-on-scroll': this.hideBarsOnScroll,
          'hide-navbar-on-scroll': this.hideNavbarOnScroll,
          'hide-toolbar-on-scroll': this.hideToolbarOnScroll,
          'hide-tabbar-on-scroll': this.hideTabbarOnScroll,
          'messages-content': this.messages,
          'login-screen-content': this.loginScreen
        }
      }
    },
    methods: {
      onPtrPullstart: function (event) {
        this.$emit('ptr:pullstart', event);
      },
      onPtrPullmove: function (event) {
        this.$emit('ptr:pullmove', event);
      },
      onPtrPullend: function (event) {
        this.$emit('ptr:pullend', event);
      },
      onPtrRefresh: function (event) {
        this.$emit('ptr:refresh', event, event.detail.done);
      },
      onPtrRefreshdone: function (event) {
        this.$emit('ptr:done', event);
      },
      onInfinite: function (event) {
        this.$emit('infinite', event);
      },
      onPageBeforeInit: function (event) {
        this.f7PageData = event.detail.page;
        this.$emit('page:beforeinit', event, event.detail.page);
      },
      onPageInit: function (event) {
        this.$emit('page:init', event, event.detail.page);
      },
      onPageReinit: function (event) {
        this.$emit('page:reinit', event, event.detail.page);
      },
      onPageBeforeAnimation: function (event) {
        this.$emit('page:beforeanimation', event, event.detail.page);
      },
      onPageAfterAnimation: function (event) {
        this.$emit('page:afteranimation', event, event.detail.page);
      },
      onPageBeforeRemove: function (event) {
        this.$emit('page:beforeremove', event, event.detail.page);
      },
      onPageBack: function (event) {
        this.$emit('page:back', event, event.detail.page);
      },
      onPageAfterBack: function (event) {
        this.$emit('page:afterback', event, event.detail.page);
      }
    }
  }
</script>


update style

update style

<template>

{{markConf.name}}

</template>


fix incorrect computed function format.

fix incorrect computed function format.

<template>

                <input type="text" class="title input" v-model="title">

Posted by {{ thread.author }} {{ thread.created | timeElapsed }}

                <textarea class="textarea" v-model="content"></textarea>

                <button @click="saveEdits()" class="button is-primary" :class="{'is-loading' : loading}">

                    Save
                </button>

                <button @click="closeEditor()" class="button is-light" :disabled=loading>

                    Close
                </button>

            {{ message }}

</template>


Fix resources not being loaded when navigating the tree

The condition doesn't make sense together with using
v-model for `selectedNodeId` - it is always evaluated
to true because values are always equal when navigating.

<template>

  <div>
    <VBreadcrumbs
      :items="breadcrumbsItems"
      divider=">"
    >
      <template v-slot:item="props">
        <span
          class="notranslate"
          :class="breadcrumbsItemClasses(props.item)"
          @click="onBreadcrumbsItemClick(props.item)"
        >
          {{ props.item.title }}
        </span>
      </template>
    </VBreadcrumbs>

    <VList>
      <template v-for="child in selectedNodeChildren">
        <VDivider :key="`divider-${child.id}`" />

        <slot
          name="child"
          :childNode="child"
        ></slot>
      </template>
    </VList>
  </div>

</template>

<script>

  import { mapGetters, mapActions } from 'vuex';

  export default {
    name: 'NodeTreeNavigation',
    model: {
      prop: 'selectedNodeId',
      event: 'updateSelectedNodeId',
    },
    props: {
      treeId: {
        type: String,
        required: true,
      },
      selectedNodeId: {
        type: String,
        required: true,
      },
    },
    computed: {
      ...mapGetters('contentNode', [
        'getContentNode',
        'getContentNodeAncestors',
        'getContentNodeChildren',
      ]),
      selectedNode() {
        return this.getContentNode(this.selectedNodeId);
      },
      selectedNodeAncestors() {
        return this.getContentNodeAncestors(this.selectedNodeId, true) || [];
      },
      selectedNodeChildren() {
        return this.getContentNodeChildren(this.selectedNodeId) || [];
      },
      breadcrumbsItems() {
        const items = [
          ...this.selectedNodeAncestors.map(node => {
            return {
              nodeId: node.id,
              title: node.title,
              disabled: false,
            };
          }),
        ];
        if (items.length > 0) {
          items[items.length - 1].disabled = true;
        }

        return items;
      },
    },
    watch: {
      selectedNodeId(newSelectedNodeId) {
        this.onSelectionUpdate(newSelectedNodeId);
      },
    },
    created() {
      this.onSelectionUpdate(this.selectedNodeId);
    },
    methods: {
      ...mapActions('contentNode', ['loadContentNode', 'loadAncestors', 'loadChildren']),
      onSelectionUpdate(nodeId) {
        this.loadContentNode(nodeId);

        if (this.selectedNode.has_children) {
          this.loadChildren({
            parent: nodeId,
            tree_id: this.treeId,
          });
        }

        this.loadAncestors({
          id: nodeId,
          includeSelf: true,
        });
      },
      breadcrumbsItemClasses(item) {
        const classes = ['breadcrumbs-item'];

        if (!item.disabled) {
          classes.push('primary--text');
        }

        return classes;
      },
      onBreadcrumbsItemClick(item) {
        this.$emit('updateSelectedNodeId', item.nodeId);
      },
    },
  };

</script>

<style lang="less" scoped>

  .breadcrumbs-item.primary--text {
    text-decoration: underline;

    &:hover {
      cursor: pointer;
    }
  }

</style>

<template>

  <div>
    <VBreadcrumbs
      :items="breadcrumbsItems"
      divider=">"
    >
      <template v-slot:item="props">
        <span
          class="notranslate"
          :class="breadcrumbsItemClasses(props.item)"
          @click="onBreadcrumbsItemClick(props.item)"
        >
          {{ props.item.title }}
        </span>
      </template>
    </VBreadcrumbs>

    <VList>
      <template v-for="child in selectedNodeChildren">
        <VDivider :key="`divider-${child.id}`" />

        <slot
          name="child"
          :childNode="child"
        ></slot>
      </template>
    </VList>
  </div>

</template>

<script>

  import { mapGetters, mapActions } from 'vuex';

  export default {
    name: 'NodeTreeNavigation',
    model: {
      prop: 'selectedNodeId',
      event: 'updateSelectedNodeId',
    },
    props: {
      treeId: {
        type: String,
        required: true,
      },
      selectedNodeId: {
        type: String,
        required: true,
      },
    },
    computed: {
      ...mapGetters('contentNode', [
        'getContentNode',
        'getContentNodeAncestors',
        'getContentNodeChildren',
      ]),
      selectedNode() {
        return this.getContentNode(this.selectedNodeId);
      },
      selectedNodeAncestors() {
        return this.getContentNodeAncestors(this.selectedNodeId, true) || [];
      },
      selectedNodeChildren() {
        return this.getContentNodeChildren(this.selectedNodeId) || [];
      },
      breadcrumbsItems() {
        const items = [
          ...this.selectedNodeAncestors.map(node => {
            return {
              nodeId: node.id,
              title: node.title,
              disabled: false,
            };
          }),
        ];
        if (items.length > 0) {
          items[items.length - 1].disabled = true;
        }

        return items;
      },
    },
    watch: {
      selectedNodeId(newSelectedNodeId) {
        if (newSelectedNodeId === this.selectedNodeId) {
          return;
        }

        this.onSelectionUpdate(newSelectedNodeId);
      },
    },
    created() {
      this.onSelectionUpdate(this.selectedNodeId);
    },
    methods: {
      ...mapActions('contentNode', ['loadContentNode', 'loadAncestors', 'loadChildren']),
      onSelectionUpdate(nodeId) {
        this.loadContentNode(nodeId);

        if (this.selectedNode.has_children) {
          this.loadChildren({
            parent: nodeId,
            tree_id: this.treeId,
          });
        }

        this.loadAncestors({
          id: nodeId,
          includeSelf: true,
        });
      },
      breadcrumbsItemClasses(item) {
        const classes = ['breadcrumbs-item'];

        if (!item.disabled) {
          classes.push('primary--text');
        }

        return classes;
      },
      onBreadcrumbsItemClick(item) {
        this.$emit('updateSelectedNodeId', item.nodeId);
      },
    },
  };

</script>

<style lang="less" scoped>

  .breadcrumbs-item.primary--text {
    text-decoration: underline;

    &:hover {
      cursor: pointer;
    }
  }

</style>


updating svg icons Vue component

updating svg icons Vue component


updated the drafting page

updated the drafting page

<template>

Draft

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a risus vel nunc ullamcorper vestibulum in sed quam. Suspendisse facilisis lacinia semper. Nulla facilisi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi pretium, tellus eget auctor faucibus, lacus mauris feugiat elit, at bibendum elit arcu sed ipsum. Donec dapibus semper ante id dapibus.

{{hero.name}}

               1st

               Melee

               Range

               Str

               Agi

               Int

          Filter

              {{ f.caption }}

          Sort

              {{ s.caption }}

      <template v-for="item in abilities" >

            {{abilities.indexOf(item)+1}}

      </template>

    <hgv-loader :color="'#ffc107'"></hgv-loader>

</template>

<template>

Draft

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a risus vel nunc ullamcorper vestibulum in sed quam. Suspendisse facilisis lacinia semper. Nulla facilisi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi pretium, tellus eget auctor faucibus, lacus mauris feugiat elit, at bibendum elit arcu sed ipsum. Donec dapibus semper ante id dapibus.

{{hero.name}}

              1st Pick

               Melee

               Range

               Str

               Agi

               Int

          Filter

              {{ f.caption }}

          Sort

              {{ s.caption }}

      <template v-for="item in abilities" >

            {{abilities.indexOf(item)+1}}

      </template>

    <hgv-loader :color="'#ffc107'"></hgv-loader>

</template>


add a "rest time" to allow the user to see the progress bar full

<template lang="html">

            Procesamiento

              Procesos Nuevos

                {{ this.pendingBatch.length }}

              Tiempo transcurrido

                <stopwatch ref="timer"></stopwatch>

  <button
    class="button is-success"
    type="button"
    @click="handleStartClick"
  >

      Procesar

  </button>

          Lote en ejecución

      <batch :programs="batch">
        <template slot="item" scope="props">

                  Turno

                    {{ props.index + 1 }}

ID:

{{ props.program.id }}

Tiempo Maximo:

{{ props.program.timeMax }} secs.

Tiempo Restante:

{{ props.program.timeMax - props.program.time }} secs.

        </template>
      </batch>

          Proceso en ejecución

      <transition name="fade">

                Tiempo Restante

                  {{ currentProcess.timeMax - currentProcess.time }}

ID:

{{ currentProcess.id }}

Operación:

{{ `${currentProcess.operation.operand1} ${currentProcess.operation.operator} ${currentProcess.operation.operand2}` }}

Tiempo Maximo:

{{ currentProcess.timeMax }} secs.

Tiempo Transcurrido:

{{ currentProcess.time }} secs.

            <progress
              class="progress is-primary"
              :value="currentProcess.time"
              :max="currentProcess.timeMax"
            >
              {{ currentProcess.time }} / {{ currentProcess.timeMax }}
            </progress>

      </transition>

          Procesos finalizados

      <batch :programs="processedPrograms">
        <template slot="item" scope="props">

                Status

                  {{ props.program.status }}

ID:

{{ props.program.id }}

Operación:

                    {{ `${props.program.operation.operand1} ${props.program.operation.operator} ${props.program.operation.operand2}` }}

Resultado:

{{ props.program.operation.result }}

        </template>
      </batch>

</template>


Fixes problem in the welcome message for users that are not in an organization

<template>

    <WelcomeFirst v-if="isFirst" :username="username" :userType="userType"></WelcomeFirst>
    <WelcomeCompact v-if="!isFirst" :username="username" :userType="userType">
      <template v-if="trialEndDate">
        {{ trialTimeLeft }}

          {{ $t('HomePage.WelcomeSection.addPaymentMethod') }}

      </template>
    </WelcomeCompact>

</template>


feat(webapp): removes SPF from the list of suggested record types

SPF record type is depricated according to RFC 7208.

This fixes #500.

<template>
  <v-combobox
    :label="label"
    :disabled="disabled || readonly"
    :error-messages="errorMessages"
    :value="value"
    :items="types"
    :required="required"
    :rules="[v => !required || !!v || 'Required.']"
    @input="input($event)"
  />
</template>

<script>
export default {
  name: 'RRSetType',
  props: {
    disabled: {
      type: Boolean,
      required: false,
    },
    errorMessages: {
      type: [String, Array],
      default: () => [],
    },
    label: {
      type: String,
      required: false,
    },
    readonly: {
      type: Boolean,
      required: false,
    },
    required: {
      type: Boolean,
      default: false,
    },
    value: {
      type: String,
      required: true,
    },
  },
  data: () => ({
    types: [
      'A',
      'AAAA',
      'MX',
      'CNAME',
      'TXT',
      'CAA',
      'NS',
      'TLSA',
      'OPENPGPKEY',
      'PTR',
      'SRV',
      'DS',
    ],
  }),
  methods: {
    input(event) {
      this.$emit('input', event);
    },
  },
};
</script>

<style>

</style>

<template>
  <v-combobox
    :label="label"
    :disabled="disabled || readonly"
    :error-messages="errorMessages"
    :value="value"
    :items="types"
    :required="required"
    :rules="[v => !required || !!v || 'Required.']"
    @input="input($event)"
  />
</template>

<script>
export default {
  name: 'RRSetType',
  props: {
    disabled: {
      type: Boolean,
      required: false,
    },
    errorMessages: {
      type: [String, Array],
      default: () => [],
    },
    label: {
      type: String,
      required: false,
    },
    readonly: {
      type: Boolean,
      required: false,
    },
    required: {
      type: Boolean,
      default: false,
    },
    value: {
      type: String,
      required: true,
    },
  },
  data: () => ({
    types: [
      'A',
      'AAAA',
      'MX',
      'CNAME',
      'TXT',
      'SPF',
      'CAA',
      'NS',
      'TLSA',
      'OPENPGPKEY',
      'PTR',
      'SRV',
      'DS',
    ],
  }),
  methods: {
    input(event) {
      this.$emit('input', event);
    },
  },
};
</script>

<style>

</style>


Add label when the small chart data is empty


Fix empty css

Fix empty css

Signed-off-by: marco <3397c7e210a9d1588196cfebb12b2c6b133f6934@pm.me>

<!--
  - @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@pm.me>
  -
  - @author Marco Ambrosini <marcoambrosini@pm.me>
  -
  - @license GNU AGPL version 3 or any later version
  -
  - This program is free software: you can redistribute it and/or modify
  - it under the terms of the GNU Affero General Public License as
  - published by the Free Software Foundation, either version 3 of the
  - License, or (at your option) any later version.
  -
  - This program is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  - GNU Affero General Public License for more details.
  -
  - You should have received a copy of the GNU Affero General Public License
  - along with this program. If not, see <http://www.gnu.org/licenses/>.
-->

<template>
	<div v-if="!loading && active">
		<template v-for="type in sharedItemsOrder">
			<SharedItems v-if="sharedItems[type]"
				:key="type"
				:type="type"
				:items="sharedItems[type]" />
		</template>
		<AppNavigationCaption :title="t('spreed', 'Projects')" />
		<CollectionList v-if="getUserId && token"
			:id="token"
			type="room"
			:name="conversation.displayName" />
	</div>
</template>

<script>
import { CollectionList } from 'nextcloud-vue-collections'
import SharedItems from './SharedItems'
import AppNavigationCaption from '@nextcloud/vue/dist/Components/AppNavigationCaption'

export default {

	name: 'SharedItemsTab',

	components: {
		SharedItems,
		CollectionList,
		AppNavigationCaption,
	},

	props: {

		active: {
			type: Boolean,
			required: true,
		},
	},

	computed: {
		getUserId() {
			return this.$store.getters.getUserId()
		},

		token() {
			return this.$store.getters.getToken()
		},

		conversation() {
			return this.$store.getters.conversation(this.token)
		},

		loading() {
			return !this.sharedItems
		},

		sharedItems() {
			return this.$store.getters.sharedItems(this.token)
		},

		// Defines the order of the sections
		sharedItemsOrder() {
			return ['media', 'file', 'voice', 'audio', 'location', 'deckcard', 'other']
		},
	},

	watch: {
		active(newValue) {
			if (newValue) {
				this.getSharedItemsOverview()
			}
		},
	},

	methods: {
		getSharedItemsOverview() {
			this.$store.dispatch('getSharedItemsOverview', { token: this.token })
		},
	},
}
</script>

<style scoped lang="scss">
</style>


adjust property name color

adjust property name color

<template>

    <slot name="title">

 0"
        class="h6 flex-md-fill mr-3 mb-0 bd-highlight myuw-font-encode-sans property-label"
        :class="{'sr-only': srOnlyTitle}"
      >
        {{ title }}

    </slot>

      <slot></slot>

</template>


components/AdGrid.vue: image-rendering: pixelated for ad images

<style lang="scss">
.adGrid {
  /* Checkerboard: */
  background-image: /* tint image */
    linear-gradient(to right, rgba(255,255,255, 0.97), rgba(255,255,255, 0.97)),
    /* checkered effect */
    linear-gradient(to right, black 50%, white 50%),
    linear-gradient(to bottom, black 50%, white 50%);
  background-blend-mode: normal, difference, normal;
  background-size: 20px 20px;
  /***/

  img, .nsfwAd, a div {
    position: absolute;
    display: block;
    overflow: hidden;
    font-size: 11px;
    color: rgba(0, 0, 0, 0.7);
    white-space: nowrap;
    image-rendering: pixelated;
  }

  .blank {
    outline: 2px solid rgba(0,0,0,0.1);
    outline-offset: -2px;
  }

  .nsfwAd {
    background: #000;
  }

  &.active img {
    box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.4) inset;
  }

  .previewAd {
    background: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(255, 255, 255, 0.9);
    z-index: 5;
    outline: 20px solid rgba(0,0,0,0.4);
  }
  .previewAd.locked {
    background: #ffcc47;
  }
}
</style>

<template>
  <div :class="{ adGrid: true, active: !!$store.state.previewAd }" :style="gridStyle(prerendered)">
    <template v-for="ad in $store.state.ads">
      <Ad :showNSFW="showNSFW" :ad="ad" :skipImage="!loadRemoteImages" v-if="ad" :key="ad.idx"></Ad>

    </template>
    <vue-draggable-resizable ref="draggable" :active="true" :minWidth="10" :minHeight="10"
      :x="$store.state.previewAd.x" :y="$store.state.previewAd.y"
      :w="80" :h="40" :grid="[10,10]" :parent="true"
      @dragstop="updatePreview" @resizestop="updatePreview"
      :draggable="!previewLocked" :resizable="!previewLocked" v-if="$store.state.previewAd" v-bind:class="{previewAd: true, locked: previewLocked}">
      <Buy :provider="provider" :contract="contract" :isReadOnly="isReadOnly" @buy="onBuy"></Buy>
    </vue-draggable-resizable>
  </div>
</template>

<script>
import Ad from './Ad.vue';
import Buy from './Buy.vue';
import VueDraggableResizable from 'vue-draggable-resizable';
import 'vue-draggable-resizable/dist/VueDraggableResizable.css';

export default {
  props: ["provider", "contract", "isReadOnly", "showNSFW", "prerendered"],
  data() {
    return {
      previewLocked: false,
      loadRemoteImages: this.prerendered ? this.prerendered.loadRemoteImages : true,
    }
  },
  methods: {
    onBuy: function (ad) {
      this.previewLocked = true;
    },
    updatePreview(x, y, width, height) {
      const dragged = this.$refs.draggable;
      this.$store.commit('updatePreview', {
        'x': dragged.left,
        'y': dragged.top,
        'width': dragged.width,
        'height': dragged.height,
      });
    },
    gridStyle(config) {
      if (!config) return;
      return {
        'background-image': 'url(' + config.image + ')',
      }
    },
  },
  components: {
    'vue-draggable-resizable': VueDraggableResizable,
    Ad,
    Buy,
  },
}
</script>

<style lang="scss">
.adGrid {
  /* Checkerboard: */
  background-image: /* tint image */
    linear-gradient(to right, rgba(255,255,255, 0.97), rgba(255,255,255, 0.97)),
    /* checkered effect */
    linear-gradient(to right, black 50%, white 50%),
    linear-gradient(to bottom, black 50%, white 50%);
  background-blend-mode: normal, difference, normal;
  background-size: 20px 20px;
  /***/

  img, .nsfwAd, a div {
    position: absolute;
    display: block;
    overflow: hidden;
    font-size: 11px;
    color: rgba(0, 0, 0, 0.7);
    white-space: nowrap;
  }

  .blank {
    outline: 2px solid rgba(0,0,0,0.1);
    outline-offset: -2px;
  }

  .nsfwAd {
    background: #000;
  }

  &.active img {
    box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.4) inset;
  }

  .previewAd {
    background: rgba(255, 255, 255, 0.8);
    border: 1px solid rgba(255, 255, 255, 0.9);
    z-index: 5;
    outline: 20px solid rgba(0,0,0,0.4);
  }
  .previewAd.locked {
    background: #ffcc47;
  }
}
</style>

<template>
  <div :class="{ adGrid: true, active: !!$store.state.previewAd }" :style="gridStyle(prerendered)">
    <template v-for="ad in $store.state.ads">
      <Ad :showNSFW="showNSFW" :ad="ad" :skipImage="!loadRemoteImages" v-if="ad" :key="ad.idx"></Ad>

    </template>
    <vue-draggable-resizable ref="draggable" :active="true" :minWidth="10" :minHeight="10"
      :x="$store.state.previewAd.x" :y="$store.state.previewAd.y"
      :w="80" :h="40" :grid="[10,10]" :parent="true"
      @dragstop="updatePreview" @resizestop="updatePreview"
      :draggable="!previewLocked" :resizable="!previewLocked" v-if="$store.state.previewAd" v-bind:class="{previewAd: true, locked: previewLocked}">
      <Buy :provider="provider" :contract="contract" :isReadOnly="isReadOnly" @buy="onBuy"></Buy>
    </vue-draggable-resizable>
  </div>
</template>

<script>
import Ad from './Ad.vue';
import Buy from './Buy.vue';
import VueDraggableResizable from 'vue-draggable-resizable';
import 'vue-draggable-resizable/dist/VueDraggableResizable.css';

export default {
  props: ["provider", "contract", "isReadOnly", "showNSFW", "prerendered"],
  data() {
    return {
      previewLocked: false,
      loadRemoteImages: this.prerendered ? this.prerendered.loadRemoteImages : true,
    }
  },
  methods: {
    onBuy: function (ad) {
      this.previewLocked = true;
    },
    updatePreview(x, y, width, height) {
      const dragged = this.$refs.draggable;
      this.$store.commit('updatePreview', {
        'x': dragged.left,
        'y': dragged.top,
        'width': dragged.width,
        'height': dragged.height,
      });
    },
    gridStyle(config) {
      if (!config) return;
      return {
        'background-image': 'url(' + config.image + ')',
      }
    },
  },
  components: {
    'vue-draggable-resizable': VueDraggableResizable,
    Ad,
    Buy,
  },
}
</script>


components/Footer.vue: New discord link

components/Footer.vue: New discord link

<template>

Authors

shazow

mveytsman

Project

<NuxtLink to="faq">FAQ</NuxtLink>

<NuxtLink to="press">Press</NuxtLink>

Source code

Twitter

Discord

OpenSea

    <slot></slot>

</template>


Changed the error-box.

Changed the error-box.

<template>

    <button class="close-button" v-on:click="hideErrorbox">X</button>

{{ $tr('errorHeader') }}

    {{ $tr('errorPrefixText') }}

      {{ error }}

</template>

<template>

{{ $tr('errorHeader') }}

    {{ $tr('errorPrefixText') }}

    <textarea id="error-textbox">
      {{ error }}
    </textarea>

</template>


change status table help

change status table help

<template>

    <colgroup slot="colgroup">
      <col class="col-name">
      <col class="col-updated">
      <col class="col-status">
      <col class="col-action">
    </colgroup>

        Name
        Last Update
        Status

        {{ row.name }}
        {{ relative(row.lastSucceededAt) }}
        OkError
        Help

</template>

<template>

    <colgroup slot="colgroup">
      <col class="col-name">
      <col class="col-updated">
      <col class="col-status">
      <col class="col-action">
    </colgroup>

        Name
        Last Update
        Status

        {{ row.name }}
        {{ relative(row.lastSucceededAt) }}
        OkError

</template>


Rename local vars

Rename local vars

<template>

      <mat-svg
        v-if="permissionType==='SUPERUSER'"
        category="toggle"
        name="star"
        class="superuser"
      />
      <mat-svg
        v-if="permissionType==='SOME_PERMISSIONS'"
        category="toggle"
        name="star"
        class="some-permissions"
      />
      <mat-svg
        v-if="permissionType==='NO_PERMISSIONS'"
        category="social"
        name="person"
        class="no-permissions"
      />
      <ui-tooltip trigger="icon">
        {{ tooltipText }}
      </ui-tooltip>

    {{ user.full_name }}

</template>


ir wip

ir wip


Use CoreTable in exam-report-page

Use CoreTable in exam-report-page

<template>

        {{ $tr('examTakenby', { num: takenBy }) }}

 0">
        {{ $tr('averageScore', { num: averageScore }) }}

    <core-table v-if="!noExamData">

{{ $tr('examReport') }}

          {{ $tr('name') }}
          {{ $tr('status') }}
          {{ $tr('score') }}
          {{ $tr('group') }}

            <content-icon
              :kind="USER"
              class="core-table-content-icon"
            />

            <k-router-link
              v-if="examTaker.progress !== undefined"
              :text="examTaker.name"
              :to="examDetailPageLink(examTaker.id)"
              class="table-name"
            />

              {{ examTaker.name }}

              {{ $tr('completed') }}

              {{ $tr('remaining', { num: (exam.question_count - examTaker.progress) }) }}

              {{ $tr('notstarted') }}

            –

              {{ $tr('scorePercentage', { num: examTaker.score / exam.question_count }) }}

          {{ examTaker.group.name || '–' }}

    </core-table>

{{ $tr('noExamData') }}

</template>

<template>

        {{ $tr('examTakenby', { num: takenBy }) }}

 0">
        {{ $tr('averageScore', { num: averageScore }) }}

{{ $tr('examReport') }}

            {{ $tr('name') }}
            {{ $tr('status') }}
            {{ $tr('score') }}
            {{ $tr('group') }}

              <k-router-link
                v-if="examTaker.progress !== undefined"
                :text="examTaker.name"
                :to="examDetailPageLink(examTaker.id)"
                class="table-name"
              />

                {{ examTaker.name }}

                {{ $tr('completed') }}

                {{ $tr('remaining', { num: (exam.question_count - examTaker.progress) }) }}

                {{ $tr('notstarted') }}

              –

                {{ $tr('scorePercentage', { num: examTaker.score / exam.question_count }) }}

            {{ examTaker.group.name || '–' }}

{{ $tr('noExamData') }}

</template>


removing unnecessary enter

removing unnecessary enter

<template>

        Editing the code of {{type}} {{item.name}} (#{{item.id}})
        Editing the code of new {{type}}

         at ({{position}})
         from toolbar #{{toolbar}}

        | This code is being tested locally
        | This block type had no code

            <button v-if="!simpleBlock && item && mine && !outdated" @click="save">Save</button>
            <button v-if="!simpleBlock && item" @click="saveAs">Fork...</button>
            <button v-if="simpleBlock || !item" @click="saveAs">Save as...</button>
            Gist
            <button v-if="(dirty || simpleBlock) && item && ((type == 'item' && toolbar) || (type == 'block' && position))" @click="test">Test</button>

{{capitalizedType}} owner

{{item.owner}} (a.k.a. you)

Gist Author

{{code.author.id}}

Gist info

ID: {{code.id}}

Revision: {{code.revision.id}}

Revision date: {{code.revision.date | moment "DD/MM/YYYY h:mm:ss A"}}

                  Newer version with ID {{item.newerVersion}}

                    <button v-if="toolbar || position" @click="update()">Update</button>

Possibly external forks/updates at {{code.lastUpdateDate | moment "DD/MM/YYYY h:mm:ss A"}}

</template>


Bugfix: Dialog needs to be completely deactivated to avoid scrolling issues.

<template>

{{question.question}}

                    <user-menu :menu-title="creatorTitle" :user="question.creator"
                               @add-trust-circle="(userId) => addUserToTrustCircle(userId)"
                               @remove-trust-circle="(userId) => removeUserFromTrustCircle(userId)">

                    </user-menu>

                        <watches-menu :user-id="question.creator.userId" :user-name="question.creator.name"
                                      :watched-id="question.questionId"
                                      watched-id-name="questionId" :user-slug="question.creator.slug"
                                      :is-logged-in-user="question.isLoggedInUser" :is-watching-action="false"
                                      :is-admin="question.isAdmin"
                                      :watched-by-user="question.userWatchesQuestion"
                                      :number-of-watches="question.numberOfWatches"
                                      menu-translation="watchesQuestion" api-get-user-command="question/watches"
                                      api-watch="user/question/watch"
                                      @add-watch="addWatch" @remove-watch="removeWatch">

                                <v-tooltip bottom>
                                    <v-btn slot="activator" small fab color="primary"
                                           v-if="!question.userWatchesQuestion"
                                           :disabled="question.isAdmin">
                                        <v-icon>mdi-star-outline</v-icon>
                                    </v-btn>
                                    <v-btn slot="activator" small fab color="user-watches-question"
                                           v-else>
                                        <v-icon>mdi-star</v-icon>
                                    </v-btn>

                            {{$t('common:feedCard.watch.userHasNotWatched')}}
                                    {{$t('common:you')}}
                            {{$t('pages:feeds.menu.watchesQuestion.titleIsLoggedInUser')}}
                                </v-tooltip>
                                {{question.numberOfWatches}}

                        </watches-menu>

                        <v-tooltip bottom>
                            <v-btn slot="activator" small fab color="primary" @click="openCreateAnswerDialog()">
                                <v-icon>mdi-forum</v-icon>
                            </v-btn>
                            {{$t('pages:feeds.menu.questions.numberOfAnswers',
                                {count: question.numberOfAnswers})}}
                        </v-tooltip>
                        {{question.numberOfAnswers}}

                    <v-spacer></v-spacer>
                    <suggestion v-if="question.isAdmin || question.isSuperUser" :is-admin="question.isAdmin"
                                :is-super-user="question.isSuperUser" :question-id="question.questionId"
                                :number-of-suggestion="question.numberOfSuggestions" id="suggestion-button-desktop">
                    </suggestion>
                    <admin-commands v-if="question.isAdmin" id="admin-button-desktop"></admin-commands>

                    <admin-commands v-if="question.isAdmin" id="admin-button-mobile"></admin-commands>
                    <suggestion v-if="question.isAdmin || question.isSuperUser" :is-admin="question.isAdmin"
                                :is-super-user="question.isSuperUser" :question-id="question.questionId"
                                :number-of-suggestion="question.numberOfSuggestions" id="suggestion-button-mobile"
                                :number-is-right-side="true">
                    </suggestion>

        <v-layout row justify-center v-if="dialog">
            <v-dialog v-model="dialog" scrollable persistent max-width="770px" :fullscreen="$vuetify.breakpoint.xsOnly">
                <create-dialog @close-dialog="dialog = false">
                </create-dialog>
            </v-dialog>
        </v-layout>

        <login-required-dialog v-if="showLoginRequired" @close-dialog="showLoginRequired = false">
        </login-required-dialog>

</template>

<template>

{{question.question}}

                    <user-menu :menu-title="creatorTitle" :user="question.creator"
                               @add-trust-circle="(userId) => addUserToTrustCircle(userId)"
                               @remove-trust-circle="(userId) => removeUserFromTrustCircle(userId)">

                    </user-menu>

                        <watches-menu :user-id="question.creator.userId" :user-name="question.creator.name"
                                      :watched-id="question.questionId"
                                      watched-id-name="questionId" :user-slug="question.creator.slug"
                                      :is-logged-in-user="question.isLoggedInUser" :is-watching-action="false"
                                      :is-admin="question.isAdmin"
                                      :watched-by-user="question.userWatchesQuestion"
                                      :number-of-watches="question.numberOfWatches"
                                      menu-translation="watchesQuestion" api-get-user-command="question/watches"
                                      api-watch="user/question/watch"
                                      @add-watch="addWatch" @remove-watch="removeWatch">

                                <v-tooltip bottom>
                                    <v-btn slot="activator" small fab color="primary"
                                           v-if="!question.userWatchesQuestion"
                                           :disabled="question.isAdmin">
                                        <v-icon>mdi-star-outline</v-icon>
                                    </v-btn>
                                    <v-btn slot="activator" small fab color="user-watches-question"
                                           v-else>
                                        <v-icon>mdi-star</v-icon>
                                    </v-btn>

                            {{$t('common:feedCard.watch.userHasNotWatched')}}
                                    {{$t('common:you')}}
                            {{$t('pages:feeds.menu.watchesQuestion.titleIsLoggedInUser')}}
                                </v-tooltip>
                                {{question.numberOfWatches}}

                        </watches-menu>

                        <v-tooltip bottom>
                            <v-btn slot="activator" small fab color="primary" @click="openCreateAnswerDialog()">
                                <v-icon>mdi-forum</v-icon>
                            </v-btn>
                            {{$t('pages:feeds.menu.questions.numberOfAnswers',
                                {count: question.numberOfAnswers})}}
                        </v-tooltip>
                        {{question.numberOfAnswers}}

                    <v-spacer></v-spacer>
                    <suggestion v-if="question.isAdmin || question.isSuperUser" :is-admin="question.isAdmin"
                                :is-super-user="question.isSuperUser" :question-id="question.questionId"
                                :number-of-suggestion="question.numberOfSuggestions" id="suggestion-button-desktop">
                    </suggestion>
                    <admin-commands v-if="question.isAdmin" id="admin-button-desktop"></admin-commands>

                    <admin-commands v-if="question.isAdmin" id="admin-button-mobile"></admin-commands>
                    <suggestion v-if="question.isAdmin || question.isSuperUser" :is-admin="question.isAdmin"
                                :is-super-user="question.isSuperUser" :question-id="question.questionId"
                                :number-of-suggestion="question.numberOfSuggestions" id="suggestion-button-mobile"
                                :number-is-right-side="true">
                    </suggestion>

        <v-layout row justify-center>
            <v-dialog v-model="dialog" scrollable persistent max-width="770px" :fullscreen="$vuetify.breakpoint.xsOnly">
                <create-dialog @close-dialog="dialog = false" v-if="dialog">
                </create-dialog>
            </v-dialog>
        </v-layout>

        <login-required-dialog v-if="showLoginRequired" @close-dialog="showLoginRequired = false">
        </login-required-dialog>

</template>