Этот коммит содержится в:
=Corey Hulen
2016-03-17 09:51:45 -07:00
родитель 074f15f761 128204b47a
Коммит 5273559ca1
90 изменённых файлов: 2766 добавлений и 1650 удалений

178
.sass-lint.yml Обычный файл
Просмотреть файл

@@ -0,0 +1,178 @@
# sass-lint config generated by make-sass-lint-config v0.1.1
#
# The following scss-lint Linters are not yet supported by sass-lint:
# DisableLinterReason, ElsePlacement, PropertyCount, SelectorDepth
# SpaceAroundOperator, TrailingWhitespace, UnnecessaryParentReference, Compass::*
#
# The following settings/values are unsupported by sass-lint:
# Linter Indentation, option "allow_non_nested_indentation"
# Linter Indentation, option "character"
# Linter NestingDepth, option "ignore_parent_selectors"
# Linter PropertySortOrder, option "min_properties"
# Linter PropertySortOrder, option "separate_groups"
# Linter SpaceBeforeBrace, option "allow_single_line_padding"
# Linter VendorPrefix, option "identifier_list"
files:
include: '**/*.scss'
options:
formatter: stylish
merge-default-rules: false
rules:
bem-depth:
- 1
- max-depth: 3
border-zero:
- 1
- convention: none
brace-style:
- 2
- allow-single-line: true
class-name-format:
- 1
- convention: hyphenatedbem
clean-import-paths:
- 1
- filename-extension: false
leading-underscore: false
empty-line-between-blocks:
- 2
- ignore-single-line-rulesets: true
extends-before-declarations: 1
extends-before-mixins: 1
final-newline:
- 1
- include: true
force-attribute-nesting: 1
force-element-nesting: 1
force-pseudo-nesting: 1
function-name-format:
- 1
- allow-leading-underscore: true
convention: hyphenatedlowercase
hex-length:
- 1
- style: short
hex-notation:
- 1
- style: lowercase
id-name-format:
- 1
- convention: hyphenatedbem
indentation:
- 2
- size: 4
leading-zero:
- 1
- include: false
mixin-name-format:
- 0
- allow-leading-underscore: true
convention: hyphenatedlowercase
mixins-before-declarations: 1
nesting-depth:
- 1
- max-depth: 4
no-color-keyword: 1
no-color-literals: 1
no-css-comments: 1
no-debug: 1
no-duplicate-properties: 1
no-empty-rulesets: 1
no-extends: 0
no-ids: 1
no-important: 1
no-invalid-hex: 1
no-mergeable-selectors: 1
no-misspelled-properties:
- 1
- extra-properties: ['overflow-scrolling', 'font-smoothing']
no-qualifying-elements:
- 1
- allow-element-with-attribute: false
allow-element-with-class: false
allow-element-with-id: false
no-trailing-zero: 1
no-transition-all: 0
no-url-protocols: 1
no-vendor-prefixes:
- 1
- additional-identifiers: []
excluded-identifiers: []
placeholder-in-extend: 1
placeholder-name-format:
- 1
- convention: hyphenatedlowercase
property-sort-order:
- 1
- ignore-custom-properties: false
property-units:
- 1
- global:
- ch
- em
- ex
- rem
- cm
- in
- mm
- pc
- pt
- px
- q
- vh
- vw
- vmin
- vmax
- deg
- grad
- rad
- turn
- ms
- s
- Hz
- kHz
- dpi
- dpcm
- dppx
- '%'
per-property: {}
quotes:
- 1
- style: single
shorthand-values:
- 1
- allowed-shorthands:
- 1
- 2
- 3
single-line-per-selector: 2
space-after-bang:
- 2
- include: false
space-after-colon:
- 2
- include: true
space-after-comma:
- 1
- include: true
space-before-bang:
- 2
- include: true
space-before-brace:
- 2
- include: true
space-before-colon: 1
space-between-parens:
- 2
- include: false
trailing-semicolon: 2
url-quotes: 1
variable-for-property:
- 0
- properties: []
variable-name-format:
- 1
- allow-leading-underscore: true
convention: hyphenatedlowercase
zero-unit: 1

4
Godeps/Godeps.json сгенерированный
Просмотреть файл

@@ -5,6 +5,10 @@
"./..."
],
"Deps": [
{
"ImportPath": "github.com/NYTimes/gziphandler",
"Rev": "a88790d49798560db24af70fb6a10a66e2549a72"
},
{
"ImportPath": "github.com/alecthomas/log4go",
"Rev": "8e9057c3b25c409a34c0b9737cdc82cbcafeabce"

13
Godeps/_workspace/src/github.com/NYTimes/gziphandler/LICENSE.md сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,13 @@
Copyright (c) 2015 The New York Times Company
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this library except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

52
Godeps/_workspace/src/github.com/NYTimes/gziphandler/README.md сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,52 @@
Gzip Handler
============
This is a tiny Go package which wraps HTTP handlers to transparently gzip the
response body, for clients which support it. Although it's usually simpler to
leave that to a reverse proxy (like nginx or Varnish), this package is useful
when that's undesirable.
## Usage
Call `GzipHandler` with any handler (an object which implements the
`http.Handler` interface), and it'll return a new handler which gzips the
response. For example:
```go
package main
import (
"io"
"net/http"
"github.com/NYTimes/gziphandler"
)
func main() {
withoutGz := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
io.WriteString(w, "Hello, World")
})
withGz := gziphandler.GzipHandler(withoutGz)
http.Handle("/", withGz)
http.ListenAndServe("0.0.0.0:8000", nil)
}
```
## Documentation
The docs can be found at [godoc.org] [docs], as usual.
## License
[Apache 2.0] [license].
[docs]: https://godoc.org/github.com/nytimes/gziphandler
[license]: https://github.com/nytimes/gziphandler/blob/master/LICENSE.md

140
Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,140 @@
package gziphandler
import (
"compress/gzip"
"fmt"
"net/http"
"strconv"
"strings"
"sync"
)
const (
vary = "Vary"
acceptEncoding = "Accept-Encoding"
contentEncoding = "Content-Encoding"
)
type codings map[string]float64
// The default qvalue to assign to an encoding if no explicit qvalue is set.
// This is actually kind of ambiguous in RFC 2616, so hopefully it's correct.
// The examples seem to indicate that it is.
const DEFAULT_QVALUE = 1.0
var gzipWriterPool = sync.Pool{
New: func() interface{} { return gzip.NewWriter(nil) },
}
// GzipResponseWriter provides an http.ResponseWriter interface, which gzips
// bytes before writing them to the underlying response. This doesn't set the
// Content-Encoding header, nor close the writers, so don't forget to do that.
type GzipResponseWriter struct {
gw *gzip.Writer
http.ResponseWriter
}
// Write appends data to the gzip writer.
func (w GzipResponseWriter) Write(b []byte) (int, error) {
return w.gw.Write(b)
}
// Flush flushes the underlying *gzip.Writer and then the underlying
// http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter
// an http.Flusher.
func (w GzipResponseWriter) Flush() {
w.gw.Flush()
if fw, ok := w.ResponseWriter.(http.Flusher); ok {
fw.Flush()
}
}
// GzipHandler wraps an HTTP handler, to transparently gzip the response body if
// the client supports it (via the Accept-Encoding header).
func GzipHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(vary, acceptEncoding)
if acceptsGzip(r) {
// Bytes written during ServeHTTP are redirected to this gzip writer
// before being written to the underlying response.
gzw := gzipWriterPool.Get().(*gzip.Writer)
defer gzipWriterPool.Put(gzw)
gzw.Reset(w)
defer gzw.Close()
w.Header().Set(contentEncoding, "gzip")
h.ServeHTTP(GzipResponseWriter{gzw, w}, r)
} else {
h.ServeHTTP(w, r)
}
})
}
// acceptsGzip returns true if the given HTTP request indicates that it will
// accept a gzippped response.
func acceptsGzip(r *http.Request) bool {
acceptedEncodings, _ := parseEncodings(r.Header.Get(acceptEncoding))
return acceptedEncodings["gzip"] > 0.0
}
// parseEncodings attempts to parse a list of codings, per RFC 2616, as might
// appear in an Accept-Encoding header. It returns a map of content-codings to
// quality values, and an error containing the errors encounted. It's probably
// safe to ignore those, because silently ignoring errors is how the internet
// works.
//
// See: http://tools.ietf.org/html/rfc2616#section-14.3
func parseEncodings(s string) (codings, error) {
c := make(codings)
e := make([]string, 0)
for _, ss := range strings.Split(s, ",") {
coding, qvalue, err := parseCoding(ss)
if err != nil {
e = append(e, err.Error())
} else {
c[coding] = qvalue
}
}
// TODO (adammck): Use a proper multi-error struct, so the individual errors
// can be extracted if anyone cares.
if len(e) > 0 {
return c, fmt.Errorf("errors while parsing encodings: %s", strings.Join(e, ", "))
}
return c, nil
}
// parseCoding parses a single conding (content-coding with an optional qvalue),
// as might appear in an Accept-Encoding header. It attempts to forgive minor
// formatting errors.
func parseCoding(s string) (coding string, qvalue float64, err error) {
for n, part := range strings.Split(s, ";") {
part = strings.TrimSpace(part)
qvalue = DEFAULT_QVALUE
if n == 0 {
coding = strings.ToLower(part)
} else if strings.HasPrefix(part, "q=") {
qvalue, err = strconv.ParseFloat(strings.TrimPrefix(part, "q="), 64)
if qvalue < 0.0 {
qvalue = 0.0
} else if qvalue > 1.0 {
qvalue = 1.0
}
}
}
if coding == "" {
err = fmt.Errorf("empty content-coding")
}
return
}

Просмотреть файл

@@ -136,6 +136,7 @@ package:
tar -C dist -czf $(DIST_PATH).tar.gz mattermost
build-client:
mkdir -p webapp/dist/files
cd webapp && make build
go-test:
@@ -196,15 +197,10 @@ clean: stop-docker
rm -Rf $(DIST_ROOT)
go clean $(GOFLAGS) -i ./...
rm -rf web/react/node_modules
rm -f web/static/js/bundle*.js
rm -f web/static/js/bundle*.js.map
rm -f web/static/js/libs*.js
rm -f web/static/css/styles.css
cd webapp && make clean
rm -rf api/data
rm -rf logs
rm -rf web/sass-files/.sass-cache
rm -rf Godeps/_workspace/pkg/
@@ -220,14 +216,17 @@ nuke: | clean clean-docker
touch $@
run: start-docker run-server run-client
run: | start-docker run-client run-server
run-server: .prepare-go
@echo Starting go web server
$(GO) run $(GOFLAGS) mattermost.go -config=config.json &
run-client: build-client
@echo Starting react processo
run-client:
@echo Starting client
mkdir -p webapp/dist/files
cd webapp && make run
@if [ "$(BUILD_ENTERPRISE)" = "true" ] && [ -d "$(ENTERPRISE_DIR)" ]; then \
cp ./config/config.json ./config/config.json.bak; \

Просмотреть файл

@@ -44,7 +44,7 @@ func InitCommand(r *mux.Router) {
sr := r.PathPrefix("/commands").Subrouter()
sr.Handle("/execute", ApiUserRequired(executeCommand)).Methods("POST")
sr.Handle("/list", ApiUserRequired(listCommands)).Methods("GET")
sr.Handle("/list", ApiUserRequired(listCommands)).Methods("POST")
sr.Handle("/create", ApiUserRequired(createCommand)).Methods("POST")
sr.Handle("/list_team_commands", ApiUserRequired(listTeamCommands)).Methods("GET")
@@ -76,7 +76,9 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
teamCmds := result.Data.([]*model.Command)
for _, cmd := range teamCmds {
if cmd.AutoComplete && !seen[cmd.Id] {
if cmd.ExternalManagement {
commands = append(commands, autocompleteCommands(c, cmd, r)...)
} else if cmd.AutoComplete && !seen[cmd.Id] {
cmd.Sanitize()
seen[cmd.Trigger] = true
commands = append(commands, cmd)
@@ -88,6 +90,92 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(model.CommandListToJson(commands)))
}
func autocompleteCommands(c *Context, cmd *model.Command, r *http.Request) []*model.Command {
props := model.MapFromJson(r.Body)
command := strings.TrimSpace(props["command"])
channelId := strings.TrimSpace(props["channelId"])
parts := strings.Split(command, " ")
trigger := parts[0][1:]
message := strings.Join(parts[1:], " ")
chanChan := Srv.Store.Channel().Get(channelId)
teamChan := Srv.Store.Team().Get(c.Session.TeamId)
userChan := Srv.Store.User().Get(c.Session.UserId)
var team *model.Team
if tr := <-teamChan; tr.Err != nil {
c.Err = tr.Err
return make([]*model.Command, 0, 32)
} else {
team = tr.Data.(*model.Team)
}
var user *model.User
if ur := <-userChan; ur.Err != nil {
c.Err = ur.Err
return make([]*model.Command, 0, 32)
} else {
user = ur.Data.(*model.User)
}
var channel *model.Channel
if cr := <-chanChan; cr.Err != nil {
c.Err = cr.Err
return make([]*model.Command, 0, 32)
} else {
channel = cr.Data.(*model.Channel)
}
l4g.Debug(fmt.Sprintf(utils.T("api.command.execute_command.debug"), trigger, c.Session.UserId))
p := url.Values{}
p.Set("token", cmd.Token)
p.Set("team_id", cmd.TeamId)
p.Set("team_domain", team.Name)
p.Set("channel_id", channelId)
p.Set("channel_name", channel.Name)
p.Set("user_id", c.Session.UserId)
p.Set("user_name", user.Username)
p.Set("command", "/"+trigger)
p.Set("text", message)
p.Set("response_url", "not supported yet")
p.Set("suggest", "true")
method := "POST"
if cmd.Method == model.COMMAND_METHOD_GET {
method = "GET"
}
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections},
}
client := &http.Client{Transport: tr}
req, _ := http.NewRequest(method, cmd.URL, strings.NewReader(p.Encode()))
req.Header.Set("Accept", "application/json")
if cmd.Method == model.COMMAND_METHOD_POST {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
if resp, err := client.Do(req); err != nil {
c.Err = model.NewLocAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error())
} else {
if resp.StatusCode == http.StatusOK {
response := model.CommandListFromJson(resp.Body)
return response
} else {
body, _ := ioutil.ReadAll(resp.Body)
c.Err = model.NewLocAppError("command", "api.command.execute_command.failed_resp.app_error", map[string]interface{}{"Trigger": trigger, "Status": resp.Status}, string(body))
}
}
return make([]*model.Command, 0, 32)
}
func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
props := model.MapFromJson(r.Body)
command := strings.TrimSpace(props["command"])
@@ -159,7 +247,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) {
teamCmds := result.Data.([]*model.Command)
for _, cmd := range teamCmds {
if trigger == cmd.Trigger {
if trigger == cmd.Trigger || cmd.ExternalManagement {
l4g.Debug(fmt.Sprintf(utils.T("api.command.execute_command.debug"), trigger, c.Session.UserId))
p := url.Values{}

Просмотреть файл

@@ -24,7 +24,10 @@ func TestListCommands(t *testing.T) {
Client.LoginByEmail(team.Name, user1.Email, "pwd")
if results, err := Client.ListCommands(); err != nil {
channel1 := &model.Channel{DisplayName: "AA", Name: "aa" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel1 = Client.Must(Client.CreateChannel(channel1)).Data.(*model.Channel)
if results, err := Client.ListCommands(channel1.Id, "/test"); err != nil {
t.Fatal(err)
} else {
commands := results.Data.([]*model.Command)

Просмотреть файл

@@ -21,7 +21,8 @@
"SessionLengthSSOInDays": 30,
"SessionCacheInMinutes": 10,
"WebsocketSecurePort": 443,
"WebsocketPort": 80
"WebsocketPort": 80,
"WebserverMode": "regular"
},
"TeamSettings": {
"SiteName": "Mattermost",
@@ -144,4 +145,4 @@
"Directory": "./data/",
"EnableDaily": false
}
}
}

Просмотреть файл

@@ -107,5 +107,5 @@ sleep 5
# ------------------------
echo starting platform
cd /mattermost/bin
cd /mattermost/mattermost/bin
./platform -config=/config_docker.json

Просмотреть файл

@@ -3131,14 +3131,14 @@
"id": "store.sql_user.get.app_error",
"translation": "We encountered an error finding the account"
},
{
"id": "store.sql_user.get_by_auth.other.app_error",
"translation": "We encountered an error trying to find the account by authentication type."
},
{
"id": "store.sql_user.get_by_auth.missing_account.app_error",
"translation": "We couldn't find an existing account matching your authentication type for this team. This team may require an invite from the team owner to join."
},
{
"id": "store.sql_user.get_by_auth.other.app_error",
"translation": "We encountered an error trying to find the account by authentication type."
},
{
"id": "store.sql_user.get_by_username.app_error",
"translation": "We couldn't find an existing account matching your username for this team. This team may require an invite from the team owner to join."

Просмотреть файл

@@ -3079,6 +3079,10 @@
"id": "store.sql_user.get_by_auth.missing_account.app_error",
"translation": "No pudimos encontrar una cuenta existente que coincida con tu tipo de autenticación para este equipo. Es posible que necesites una invitación por parte del dueño del equipo para unirte."
},
{
"id": "store.sql_user.get_by_auth.other.app_error",
"translation": "Encontramos un error tratando de identificar la cuenta con este tipo de autenticación."
},
{
"id": "store.sql_user.get_by_username.app_error",
"translation": "No pudimos encontrar una cuenta existente que coincida con tu nombre de usuario para este equipo. Es posible que necesites una invitación por parte del dueño del equipo para unirte."

Просмотреть файл

@@ -363,8 +363,11 @@ func (c *Client) Command(channelId string, command string, suggest bool) (*Resul
}
}
func (c *Client) ListCommands() (*Result, *AppError) {
if r, err := c.DoApiGet("/commands/list", "", ""); err != nil {
func (c *Client) ListCommands(channelId string, command string) (*Result, *AppError) {
m := make(map[string]string)
m["command"] = command
m["channelId"] = channelId
if r, err := c.DoApiPost("/commands/list", MapToJson(m)); err != nil {
return nil, err
} else {
return &Result{r.Header.Get(HEADER_REQUEST_ID),

Просмотреть файл

@@ -14,22 +14,23 @@ const (
)
type Command struct {
Id string `json:"id"`
Token string `json:"token"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
CreatorId string `json:"creator_id"`
TeamId string `json:"team_id"`
Trigger string `json:"trigger"`
Method string `json:"method"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
AutoComplete bool `json:"auto_complete"`
AutoCompleteDesc string `json:"auto_complete_desc"`
AutoCompleteHint string `json:"auto_complete_hint"`
DisplayName string `json:"display_name"`
URL string `json:"url"`
Id string `json:"id"`
Token string `json:"token"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
CreatorId string `json:"creator_id"`
TeamId string `json:"team_id"`
ExternalManagement bool `json:"external_management"`
Trigger string `json:"trigger"`
Method string `json:"method"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
AutoComplete bool `json:"auto_complete"`
AutoCompleteDesc string `json:"auto_complete_desc"`
AutoCompleteHint string `json:"auto_complete_hint"`
DisplayName string `json:"display_name"`
URL string `json:"url"`
}
func (o *Command) ToJson() string {

Просмотреть файл

@@ -21,6 +21,10 @@ const (
SERVICE_GITLAB = "gitlab"
SERVICE_GOOGLE = "google"
WEBSERVER_MODE_REGULAR = "regular"
WEBSERVER_MODE_GZIP = "gzip"
WEBSERVER_MODE_DISABLED = "disabled"
)
type ServiceSettings struct {
@@ -46,6 +50,7 @@ type ServiceSettings struct {
SessionCacheInMinutes *int
WebsocketSecurePort *int
WebsocketPort *int
WebserverMode *string
}
type SSOSettings struct {
@@ -391,6 +396,11 @@ func (o *Config) SetDefaults() {
*o.ServiceSettings.AllowCorsFrom = ""
}
if o.ServiceSettings.WebserverMode == nil {
o.ServiceSettings.WebserverMode = new(string)
*o.ServiceSettings.WebserverMode = "regular"
}
if o.ComplianceSettings.Enable == nil {
o.ComplianceSettings.Enable = new(bool)
*o.ComplianceSettings.Enable = false

Просмотреть файл

@@ -34,6 +34,7 @@ func NewSqlCommandStore(sqlStore *SqlStore) CommandStore {
}
func (s SqlCommandStore) UpgradeSchemaIfNeeded() {
s.CreateColumnIfNotExists("Commands", "ExternalManagement", "tinyint(1)", "boolean", "0")
}
func (s SqlCommandStore) CreateIndexesIfNotExists() {

Просмотреть файл

@@ -7,6 +7,8 @@ import (
"net/http"
"strings"
"github.com/NYTimes/gziphandler"
l4g "github.com/alecthomas/log4go"
"github.com/mattermost/platform/api"
"github.com/mattermost/platform/model"
@@ -23,11 +25,17 @@ func InitWeb() {
mainrouter := api.Srv.Router
staticDir := utils.FindDir(CLIENT_DIR)
l4g.Debug("Using client directory at %v", staticDir)
mainrouter.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))
if *utils.Cfg.ServiceSettings.WebserverMode != "disabled" {
staticDir := utils.FindDir(CLIENT_DIR)
l4g.Debug("Using client directory at %v", staticDir)
if *utils.Cfg.ServiceSettings.WebserverMode == "gzip" {
mainrouter.PathPrefix("/static/").Handler(gziphandler.GzipHandler(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))))
} else {
mainrouter.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir))))
}
mainrouter.Handle("/{anything:.*}", api.AppHandlerIndependent(root)).Methods("GET")
mainrouter.Handle("/{anything:.*}", api.AppHandlerIndependent(root)).Methods("GET")
}
}
var browsersNotSupported string = "MSIE/8;MSIE/9;MSIE/10;Internet Explorer/8;Internet Explorer/9;Internet Explorer/10;Safari/7;Safari/8"

Просмотреть файл

@@ -1,4 +1,4 @@
.PHONY: build test
.PHONY: build test run clean
test:
@echo Checking for style guide compliance
@@ -12,7 +12,20 @@ test:
touch $@
build: .npminstall
@echo Building mattermost web client
build: | .npminstall test
@echo Building mattermost Webapp
npm run build
run: .npminstall
@echo Running mattermost Webapp for development
npm run run
clean:
@echo Cleaning Webapp
rm -rf dist
rm -rf node_modules
rm .npminstall

Просмотреть файл

@@ -120,7 +120,10 @@ export default class CenterPanel extends React.Component {
id='app-content'
className='app__content'
>
<div id='channel-header'>
<div
id='channel-header'
className='channel-header'
>
<ChannelHeader
user={this.state.user}
/>

101
webapp/components/code_preview.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,101 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import $ from 'jquery';
import * as syntaxHightlighting from 'utils/syntax_hightlighting.jsx';
import Constants from 'utils/constants.jsx';
import FileInfoPreview from './file_info_preview.jsx';
import React from 'react';
export default class CodePreview extends React.Component {
constructor(props) {
super(props);
this.updateStateFromProps = this.updateStateFromProps.bind(this);
this.handleReceivedError = this.handleReceivedError.bind(this);
this.handleReceivedCode = this.handleReceivedCode.bind(this);
this.state = {
code: '',
lang: '',
loading: true,
success: true
};
}
componentDidMount() {
this.updateStateFromProps(this.props);
}
componentWillReceiveProps(nextProps) {
if (this.props.fileUrl !== nextProps.fileUrl) {
this.updateStateFromProps(nextProps);
}
}
updateStateFromProps(props) {
var usedLanguage = syntaxHightlighting.getLang(props.filename);
if (!usedLanguage || props.fileInfo.size > Constants.CODE_PREVIEW_MAX_FILE_SIZE) {
this.setState({code: '', lang: '', loading: false, success: false});
return;
}
this.setState({code: '', lang: usedLanguage, loading: true});
$.ajax({
async: true,
url: props.fileUrl,
type: 'GET',
error: this.handleReceivedError,
success: this.handleReceivedCode
});
}
handleReceivedCode(data) {
const parsed = syntaxHightlighting.formatCode(this.state.lang, data, this.props.filename);
this.setState({code: parsed, loading: false, success: true});
}
handleReceivedError() {
this.setState({loading: false, success: false});
}
static support(filename) {
return typeof syntaxHightlighting.getLang(filename) !== 'undefined';
}
render() {
if (this.state.loading) {
return (
<div className='view-image__loading'>
<img
className='loader-image'
src='/static/images/load.gif'
/>
</div>
);
}
if (!this.state.success) {
return (
<FileInfoPreview
filename={this.props.filename}
fileUrl={this.props.fileUrl}
fileInfo={this.props.fileInfo}
formatMessage={this.props.formatMessage}
/>
);
}
return <div dangerouslySetInnerHTML={{__html: this.state.code}}/>;
}
}
CodePreview.propTypes = {
filename: React.PropTypes.string.isRequired,
fileUrl: React.PropTypes.string.isRequired,
fileInfo: React.PropTypes.object.isRequired,
formatMessage: React.PropTypes.func.isRequired
};

Просмотреть файл

@@ -160,7 +160,7 @@ export default class MoreChannels extends React.Component {
return (
<div
className='modal fade'
className='modal fade more-channel__modal'
id='more_channels'
ref='modal'
tabIndex='-1'

Просмотреть файл

@@ -38,7 +38,7 @@ class NewChannelModal extends React.Component {
}
componentDidMount() {
if (Utils.isBrowserIE()) {
$('body').addClass('browser--IE');
$('body').addClass('browser--ie');
}
}
handleSubmit(e) {

Просмотреть файл

@@ -158,6 +158,7 @@ export default class PopoverListMembers extends React.Component {
<Popover
ref='memebersPopover'
title={title}
className='member-list__popover'
id='member-list-popover'
>
<div className='more-modal__list'>{popoverHtml}</div>

Просмотреть файл

@@ -37,9 +37,9 @@ CommandSuggestion.propTypes = {
};
export default class CommandProvider {
handlePretextChanged(suggestionId, pretext) {
handlePretextChanged(suggestionId, pretext, channelId) {
if (pretext.startsWith('/')) {
AsyncClient.getSuggestedCommands(pretext, suggestionId, CommandSuggestion);
AsyncClient.getSuggestedCommands(pretext, channelId, suggestionId, CommandSuggestion);
}
}
}

Просмотреть файл

@@ -111,7 +111,7 @@ export default class SuggestionBox extends React.Component {
handlePretextChanged(pretext) {
for (const provider of this.props.providers) {
provider.handlePretextChanged(this.suggestionId, pretext);
provider.handlePretextChanged(this.suggestionId, pretext, this.props.channelId);
}
}
@@ -160,6 +160,7 @@ SuggestionBox.propTypes = {
value: React.PropTypes.string.isRequired,
onUserInput: React.PropTypes.func,
providers: React.PropTypes.arrayOf(React.PropTypes.object),
channelId: React.PropTypes.string,
// explicitly name any input event handlers we override and need to manually call
onChange: React.PropTypes.func,

Просмотреть файл

@@ -224,6 +224,7 @@ export default class Textbox extends React.Component {
style={{visibility: this.state.preview ? 'hidden' : 'visible'}}
listComponent={SuggestionList}
providers={this.suggestionProviders}
channelId={this.props.channelId}
/>
<div
ref='preview'

Просмотреть файл

@@ -4,9 +4,13 @@
import LoadingScreen from '../loading_screen.jsx';
import * as Client from 'utils/client.jsx';
import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl';
const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES;
const holders = defineMessages({
requestTypePost: {
id: 'user.settings.cmds.request_type_post',
@@ -59,6 +63,7 @@ export default class ManageCommandCmds extends React.Component {
this.getCmds = this.getCmds.bind(this);
this.addNewCmd = this.addNewCmd.bind(this);
this.emptyCmd = this.emptyCmd.bind(this);
this.updateExternalManagement = this.updateExternalManagement.bind(this);
this.updateTrigger = this.updateTrigger.bind(this);
this.updateURL = this.updateURL.bind(this);
this.updateMethod = this.updateMethod.bind(this);
@@ -99,7 +104,7 @@ export default class ManageCommandCmds extends React.Component {
addNewCmd(e) {
e.preventDefault();
if (this.state.cmd.trigger === '' || this.state.cmd.url === '') {
if (this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management)) {
return;
}
@@ -189,6 +194,12 @@ export default class ManageCommandCmds extends React.Component {
);
}
updateExternalManagement(e) {
var cmd = this.state.cmd;
cmd.external_management = e.target.checked;
this.setState(cmd);
}
updateTrigger(e) {
var cmd = this.state.cmd;
cmd.trigger = e.target.value;
@@ -270,11 +281,26 @@ export default class ManageCommandCmds extends React.Component {
);
}
let slashCommandAutocompleteDiv;
if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) {
slashCommandAutocompleteDiv = (
<div className='padding-top x2'>
<strong>
<FormattedMessage
id='user.settings.cmds.external_management'
defaultMessage='External management: '
/>
</strong><span className='word-break--all'>{cmd.external_management ? this.props.intl.formatMessage(holders.autocompleteYes) : this.props.intl.formatMessage(holders.autocompleteNo)}</span>
</div>
);
}
cmds.push(
<div
key={cmd.id}
className='webhook__item webcmd__item'
>
{slashCommandAutocompleteDiv}
{triggerDiv}
<div className='padding-top x2 webcmd__url'>
<strong>
@@ -416,7 +442,170 @@ export default class ManageCommandCmds extends React.Component {
</div>
);
const disableButton = this.state.cmd.trigger === '' || this.state.cmd.url === '';
const disableButton = this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management);
let triggerInput;
if (!this.state.cmd.external_management) {
triggerInput = (
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.trigger'
defaultMessage='Command Trigger Word: '
/>
</label>
<div className='padding-top'>
<input
ref='trigger'
className='form-control'
value={this.state.cmd.trigger}
onChange={this.updateTrigger}
placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.trigger_desc'
defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug'
/>
</div>
</div>
);
}
let slashCommandAutocompleteCheckbox;
if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) {
slashCommandAutocompleteCheckbox = (
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.external_management'
defaultMessage='External management: '
/>
</label>
<div className='padding-top'>
<div className='checkbox'>
<label>
<input
type='checkbox'
checked={this.state.cmd.external_management}
onChange={this.updateExternalManagement}
/>
<FormattedMessage
id='user.settings.cmds.slashCmd_autocmp'
defaultMessage='Enable external application to offer autocomplete'
/>
</label>
</div>
</div>
</div>
);
}
let autoCompleteSettings;
if (!this.state.cmd.external_management) {
autoCompleteSettings = (
<div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete'
defaultMessage='Autocomplete: '
/>
</label>
<div className='padding-top'>
<div className='checkbox'>
<label>
<input
type='checkbox'
checked={this.state.cmd.auto_complete}
onChange={this.updateAutoComplete}
/>
<FormattedMessage
id='user.settings.cmds.auto_complete_help'
defaultMessage=' Show this command in the autocomplete list.'
/>
</label>
</div>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint'
defaultMessage='Autocomplete Hint: '
/>
</label>
<div className='padding-top'>
<input
ref='autoCompleteHint'
className='form-control'
value={this.state.cmd.auto_complete_hint}
onChange={this.updateAutoCompleteHint}
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint_desc'
defaultMessage='Optional hint in the autocomplete list about parameters needed for command.'
/>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete_desc'
defaultMessage='Autocomplete Description: '
/>
</label>
<div className='padding-top'>
<input
ref='autoCompleteDesc'
className='form-control'
value={this.state.cmd.auto_complete_desc}
onChange={this.updateAutoCompleteDesc}
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.auto_complete_desc_desc'
defaultMessage='Optional short description of slash command for the autocomplete list.'
/>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.display_name'
defaultMessage='Descriptive Label: '
/>
</label>
<div className='padding-top'>
<input
ref='displayName'
className='form-control'
value={this.state.cmd.display_name}
onChange={this.updateDisplayName}
placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.cmd_display_name'
defaultMessage='Brief description of slash command to show in listings.'
/>
</div>
{addError}
</div>
</div>
);
}
return (
<div key='addCommandCmd'>
@@ -433,29 +622,8 @@ export default class ManageCommandCmds extends React.Component {
<div className='padding-top divider-light'></div>
<div className='padding-top'>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.trigger'
defaultMessage='Command Trigger Word: '
/>
</label>
<div className='padding-top'>
<input
ref='trigger'
className='form-control'
value={this.state.cmd.trigger}
onChange={this.updateTrigger}
placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.trigger_desc'
defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug'
/>
</div>
</div>
{slashCommandAutocompleteCheckbox}
{triggerInput}
<div className='padding-top x2'>
<label className='control-label'>
@@ -560,102 +728,7 @@ export default class ManageCommandCmds extends React.Component {
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete'
defaultMessage='Autocomplete: '
/>
</label>
<div className='padding-top'>
<div className='checkbox'>
<label>
<input
type='checkbox'
checked={this.state.cmd.auto_complete}
onChange={this.updateAutoComplete}
/>
<FormattedMessage
id='user.settings.cmds.auto_complete_help'
defaultMessage=' Show this command in the autocomplete list.'
/>
</label>
</div>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint'
defaultMessage='Autocomplete Hint: '
/>
</label>
<div className='padding-top'>
<input
ref='autoCompleteHint'
className='form-control'
value={this.state.cmd.auto_complete_hint}
onChange={this.updateAutoCompleteHint}
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.auto_complete_hint_desc'
defaultMessage='Optional hint in the autocomplete list about parameters needed for command.'
/>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.auto_complete_desc'
defaultMessage='Autocomplete Description: '
/>
</label>
<div className='padding-top'>
<input
ref='autoCompleteDesc'
className='form-control'
value={this.state.cmd.auto_complete_desc}
onChange={this.updateAutoCompleteDesc}
placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.auto_complete_desc_desc'
defaultMessage='Optional short description of slash command for the autocomplete list.'
/>
</div>
</div>
<div className='padding-top x2'>
<label className='control-label'>
<FormattedMessage
id='user.settings.cmds.display_name'
defaultMessage='Descriptive Label: '
/>
</label>
<div className='padding-top'>
<input
ref='displayName'
className='form-control'
value={this.state.cmd.display_name}
onChange={this.updateDisplayName}
placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)}
/>
</div>
<div className='padding-top'>
<FormattedMessage
id='user.settings.cmds.cmd_display_name'
defaultMessage='Brief description of slash command to show in listings.'
/>
</div>
{addError}
</div>
{autoCompleteSettings}
<div className='padding-top x2 padding-bottom'>
<a

Просмотреть файл

@@ -51,6 +51,10 @@ const holders = defineMessages({
EMBED_TOGGLE: {
id: 'user.settings.advance.embed_toggle',
defaultMessage: 'Show toggle for all embed previews'
},
SLASHCMD_AUTOCMP: {
id: 'user.settings.advance.slashCmd_autocmp',
defaultMessage: 'Enable external application to offer slash command autocomplete'
}
});

Просмотреть файл

@@ -195,7 +195,7 @@ export default class UserSettingsDisplay extends React.Component {
const showUsername = (
<FormattedMessage
id='user.settings.display.showUsername'
defaultMessage='Show username (team default)'
defaultMessage='Show username (default)'
/>
);
const showNickname = (

Просмотреть файл

@@ -7,6 +7,7 @@ import * as Client from 'utils/client.jsx';
import * as Utils from 'utils/utils.jsx';
import AudioVideoPreview from './audio_video_preview.jsx';
import Constants from 'utils/constants.jsx';
import CodePreview from './code_preview.jsx';
import FileInfoPreview from './file_info_preview.jsx';
import FileStore from 'stores/file_store.jsx';
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
@@ -254,6 +255,15 @@ class ViewImageModal extends React.Component {
formatMessage={this.props.intl.formatMessage}
/>
);
} else if (CodePreview.support(filename)) {
content = (
<CodePreview
filename={filename}
fileUrl={fileUrl}
fileInfo={fileInfo}
formatMessage={this.props.intl.formatMessage}
/>
);
} else {
content = (
<FileInfoPreview
@@ -311,18 +321,19 @@ class ViewImageModal extends React.Component {
<Modal
show={this.props.show}
onHide={this.props.onModalDismissed}
className='image_modal'
className='modal-image'
dialogClassName='modal-image'
>
<Modal.Body
modalClassName='image-body'
modalClassName='modal-image__body'
onClick={this.props.onModalDismissed}
>
<div
className={'image-wrapper'}
className={'modal-image__wrapper'}
onClick={this.props.onModalDismissed}
>
<div
className='modal-back'
onMouseEnter={this.onMouseEnterImage}
onMouseLeave={this.onMouseLeaveImage}
onClick={(e) => e.stopPropagation()}

Просмотреть файл

@@ -1126,6 +1126,7 @@
"tutorial_tip.seen": "Seen this before? ",
"upload_overlay.info": "Drop a file to upload it.",
"user.settings.advance.embed_preview": "Show preview snippet of links below message",
"user.settings.advance.slashCmd_autocmp": "Enable external application to offer slash command autocomplete",
"user.settings.advance.embed_toggle": "Show toggle for all embed previews",
"user.settings.advance.enabled": "enabled",
"user.settings.advance.feature": " Feature ",
@@ -1173,6 +1174,7 @@
"user.settings.cmds.url_desc": "The callback URL to receive the HTTP POST or GET event request when the slash command is run.",
"user.settings.cmds.username": "Response Username: ",
"user.settings.cmds.username_desc": "Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols \"-\", \"_\", and \".\" .",
"user.settings.cmds.slashCmd_autocmp": "Enable external application to offer autocomplete",
"user.settings.custom_theme.awayIndicator": "Away Indicator",
"user.settings.custom_theme.buttonBg": "Button BG",
"user.settings.custom_theme.buttonColor": "Button Text",
@@ -1209,7 +1211,7 @@
"user.settings.display.preferTime": "Select how you prefer time displayed.",
"user.settings.display.showFullname": "Show first and last name",
"user.settings.display.showNickname": "Show nickname if one exists, otherwise show first and last name",
"user.settings.display.showUsername": "Show username (team default)",
"user.settings.display.showUsername": "Show username (default)",
"user.settings.display.teammateDisplay": "Teammate Name Display",
"user.settings.display.theme.customTheme": "Custom Theme",
"user.settings.display.theme.describe": "Open to manage your theme",

Просмотреть файл

@@ -1174,7 +1174,7 @@
"user.settings.display.preferTime": "Selecione como você prefere que a hora seja mostrada.",
"user.settings.display.showFullname": "Mostrar primeiro e último nome",
"user.settings.display.showNickname": "Mostras apelidos se um existir, caso contrário mostrar o primeiro e último nome",
"user.settings.display.showUsername": "Mostrar nome de usuário (equipe padrão)",
"user.settings.display.showUsername": "Mostrar nome de usuário (padrão)",
"user.settings.display.teammateDisplay": "Nome de Exibição da Equipe de Trabalho",
"user.settings.display.theme.customTheme": "Tema Customizado",
"user.settings.display.theme.describe": "Abrir para gerenciar seu tema",
@@ -1313,4 +1313,4 @@
"web.footer.terms": "Termos",
"web.header.back": "Voltar",
"web.root.singup_info": "Toda comunicação em um só lugar, pesquisável e acessível em qualquer lugar"
}
}

Просмотреть файл

@@ -31,7 +31,7 @@
"babel-loader": "6.2.4",
"babel-plugin-transform-runtime": "6.6.0",
"babel-polyfill": "6.7.2",
"babel-preset-es2015": "6.6.0",
"babel-preset-es2015-webpack": "6.4.0",
"babel-preset-react": "6.5.0",
"babel-preset-stage-0": "6.5.0",
"eslint": "2.2.0",
@@ -39,6 +39,7 @@
"exports-loader": "0.6.3",
"extract-text-webpack-plugin": "1.0.1",
"file-loader": "0.8.5",
"url-loader": "0.5.7",
"html-loader": "0.4.3",
"copy-webpack-plugin": "1.1.1",
"css-loader": "0.23.1",
@@ -52,6 +53,7 @@
},
"scripts": {
"check": "eslint --ext \".jsx\" --ignore-pattern node_modules --quiet .",
"build": "webpack --progress"
"build": "webpack --optimize-dedupe",
"run": "webpack --progress"
}
}

Просмотреть файл

@@ -3,11 +3,11 @@
import $ from 'jquery';
import 'sass/styles.scss';
import 'bootstrap/dist/css/bootstrap.css';
import 'jasny-bootstrap/dist/css/jasny-bootstrap.css';
import 'bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css';
import 'google-fonts/google-fonts.css';
import 'sass/styles.scss';
import React from 'react';
import ReactDOM from 'react-dom';

Просмотреть файл

@@ -6,22 +6,24 @@ body {
}
body {
width: 100%;
height: 100%;
background: $bg--gray;
height: 100%;
position: relative;
width: 100%;
}
&.sticky {
background: $bg--white;
.sticky {
background: $white;
> .container-fluid {
overflow: auto;
}
> .container-fluid {
overflow: auto;
}
.inner-wrap {
> .row.content {
min-height: 100%;
.inner-wrap {
> .row {
&.content {
margin-bottom: -89px;
min-height: 100%;
}
}
}
@@ -30,9 +32,11 @@ body {
.inner-wrap {
height: 100%;
> .row.main {
height: 100%;
position: relative;
> .row {
&.main {
height: 100%;
position: relative;
}
}
}

Просмотреть файл

@@ -6,20 +6,20 @@ strong {
}
a {
color: $primary-color;
cursor: pointer;
text-decoration: none;
word-break: break-word;
color: $color--primary;
}
a:focus,
a:hover {
color: $color--primary--hover;
&:focus,
&:hover {
color: $primary-color--hover;
}
}
body {
@include font-smoothing;
font-family: 'Open Sans', sans-serif;
-webkit-font-smoothing: antialiased;
}
.word-break--all {

Просмотреть файл

@@ -1,13 +1,13 @@
@charset 'UTF-8';
.alert {
padding: 8px 12px;
@include border-radius($border-rad);
padding: 8px 12px;
}
.alert--confirm {
display: inline-block;
float: left;
padding: 4px 10px;
margin: 1px 0 0 10px;
}
padding: 4px 10px;
}

Просмотреть файл

@@ -5,19 +5,19 @@
@include border-radius($border-rad);
&.btn-primary {
background: $primary-color;
border-color: transparent;
background: $color--primary;
&:hover,
&:focus,
&:active {
background: $color--primary--hover;
background: $primary-color--hover;
}
}
&.btn-inactive {
background: $light-gray;
border-color: transparent;
background: #707070;
color: #fff;
color: $white;
}
}

Просмотреть файл

@@ -1,27 +1,27 @@
@charset 'UTF-8';
.emoticon {
width: 1.5em;
height: 1.5em;
display: inline-block;
margin-bottom: .25em;
background-size: contain;
display: inline-block;
height: 1.5em;
margin-bottom: .25em;
width: 1.5em;
}
.emoticon-suggestion {
@include clearfix;
width: 100%;
height: 30px;
cursor: pointer;
font-size: 13px;
height: 30px;
line-height: 30px;
width: 100%;
}
.emoticon-suggestion__image {
width: 20px;
height: 20px;
margin: 6px 6px 0 5px;
padding: 0;
text-align: center;
vertical-align: top;
width: 20px;
}

Просмотреть файл

@@ -1,29 +1,28 @@
@charset 'UTF-8';
.error-bar {
background-color: #09f;
text-align: center;
position: relative;
color: #fff;
background-color: darken($primary-color, 5%);
color: $white;
padding: 5px 30px;
position: absolute;
text-align: center;
top: 0;
width: 100%;
z-index: 9999;
padding: 5px 30px;
&__close {
position: absolute;
right: 0;
top: 0;
color: #fff;
color: $white;
font-family: 'Open Sans', sans-serif;
font-size: 20px;
font-weight: 600;
text-decoration: none;
padding: 0 10px;
font-family: 'Open Sans', sans-serif;
position: absolute;
right: 0;
text-decoration: none;
top: 0;
&:hover {
color: #fff;
color: $white;
text-decoration: none;
}
}

Просмотреть файл

@@ -1,27 +1,31 @@
@charset 'UTF-8';
.file-preview__container {
position: relative;
margin: 1px 0 10px;
width: 100%;
max-height: 100px;
height: 100px;
white-space: nowrap;
margin: 1px 0 10px;
max-height: 100px;
overflow-x: auto;
overflow-y: hidden;
position: relative;
white-space: nowrap;
width: 100%;
}
.file-preview {
@include clearfix;
border: 1px solid $light-gray;
display: inline-block;
width: 120px;
height: 100px;
margin: 0 0 0 10px;
position: relative;
border: 1px solid #ddd;
@include clearfix;
width: 120px;
&:hover .file-preview__remove:after {
@include opacity(1);
&:hover {
.file-preview__remove {
&:after {
@include opacity(1);
}
}
}
&:first-child {
@@ -29,13 +33,13 @@
}
.spinner {
position: absolute;
top: 50%;
height: 32px;
left: 50%;
margin-left: -16px;
margin-top: -16px;
position: absolute;
top: 50%;
width: 32px;
height: 32px;
}
}
@@ -46,14 +50,15 @@
}
.file-preview__remove {
position: absolute;
width: 100%;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
&:after {
background: rgba(0, 0, 0, .4);
@include opacity(0);
@include alpha-property(background, $black, .4);
content: '';
height: 100%;
left: 0;
@@ -61,33 +66,31 @@
position: absolute;
top: 0;
width: 100%;
@include opacity(0);
}
i {
top: 5px;
right: 5px;
position: absolute;
color: #fff;
color: $white;
cursor: pointer;
z-index: 5;
opacity: inherit;
text-shadow: 0 0px 3px #444;
text-shadow: 0 0px 3px rgba(0, 0, 0, .7);
position: absolute;
right: 5px;
text-shadow: 0 0 3px alpha-color($black, .7);
top: 5px;
z-index: 5;
}
}
.image-comment {
background-position: left top;
background-repeat: no-repeat;
width: 300px;
height: 300px;
width: 300px;
}
.file-icon {
width: 100%;
height: 100%;
width: 100%;
&.audio {
@include file-icon('../images/icons/audio.png');
@@ -131,36 +134,30 @@
}
.post-image__column {
border: 1px solid alpha-color($black, .2);
float: left;
height: 100px;
margin: 5px 10px 5px 0;
position: relative;
width: 240px;
height: 100px;
float: left;
margin: 5px 10px 5px 0;
border: 1px solid lightgrey;
a {
text-decoration: none;
color: grey;
}
}
.post-image__load {
background-position: center;
background-repeat: no-repeat;
background-size: 20px 20px;
height: 100%;
width: 100%;
background-size: 20px 20px;
background-repeat: no-repeat;
background-position: center;
background-image: url('~images/load.gif');
}
.post-image {
width: 100%;
height: 100%;
background-color: #fff;
background-color: $white;
background-repeat: no-repeat;
height: 100%;
overflow: hidden;
position: relative;
text-align: center;
width: 100%;
&.small {
background-position: center;
@@ -170,60 +167,59 @@
background-position: top left;
}
.spinner.file__loading {
position: absolute;
left: 50%;
margin-left: -16px;
top: 50%;
margin-top: -16px;
.spinner {
.file__loading {
left: 50%;
margin-left: -16px;
margin-top: -16px;
position: absolute;
top: 50%;
}
}
.file__loaded {
max-width: initial;
&.landscape,
&.quadrat {
height: 100px;
}
&.portrait {
width: 120px;
}
}
&:hover .file-playback__controls.stop {
@include opacity(1);
}
}
.post-image__thumbnail {
@include cursor(zoom-in);
float: left;
width: 50%;
height: 100%;
cursor: zoom-in;
cursor: -webkit-zoom-in;
width: 50%;
}
.post-image__details {
float: left;
@include clearfix;
word-break: break-word;
width: 50%;
height: 100%;
background: white;
border-left: 1px solid #ddd;
background: $white;
border-left: 1px solid $light-gray;
color: alpha-color($black, .8);
float: left;
font-size: 13px;
height: 100%;
padding: 7px;
color: #333;
width: 50%;
word-break: break-word;
.post-image__name {
margin-bottom: 3px;
display: block;
margin-bottom: 3px;
}
.post-image__download {
@include opacity(.7);
cursor: pointer;
display: inline-block;
padding-right: 7px;
cursor: pointer;
@include opacity(.7);
}
.post-image__type {
@@ -231,57 +227,56 @@
}
.post-image__size {
margin-left: 4px;
@include opacity(.6);
margin-left: 4px;
}
}
.file-details__container {
@include display-flex;
display: -ms-flexbox;
background: $white;
.file-details {
width: 320px;
height: 270px;
padding: 14px;
text-align: left;
vertical-align: top;
width: 320px;
.file-details__name {
color: #333;
color: alpha-color($black, .9);
font-size: 16px;
}
.file-details__info {
color: grey;
color: alpha-color($black, .5);
}
}
.file-details__preview {
width: 320px;
border-right: 1px solid $light-gray;
height: 270px;
border-right: 1px solid #ddd;
vertical-align: center;
width: 320px;
// helper to center the image icon in the preview window
.file-details__preview-helper {
height: 100%;
display: inline-block;
height: 100%;
vertical-align: middle;
}
}
}
.file-playback__controls {
@include single-transition(opacity, .6s);
bottom: 0;
cursor: pointer;
font-size: 22px;
position: absolute;
right: 5px;
bottom: 0;
font-size: 22px;
cursor: pointer;
z-index: 2;
-webkit-transition: opacity .6s;
-moz-transition: opacity .6s;
-o-transition: opacity .6s;
transition: opacity .6s;
z-index: 2;
&.stop {
@include opacity(0);
@@ -289,6 +284,6 @@
}
.view-image__loading {
background: black;
background: $black;
min-height: 100px;
}

Просмотреть файл

@@ -15,12 +15,21 @@
&.no-resize {
resize: none;
}
&[disabled],
[readonly] {
@include alpha-property(background, $white, .1);
color: inherit;
cursor: auto;
}
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
cursor: auto;
background: rgba(#fff, .1);
color: inherit;
fieldset {
&[disabled] {
.form-control {
@include alpha-property(background, $white, .1);
color: inherit;
cursor: auto;
}
}
}

Просмотреть файл

@@ -1,23 +1,22 @@
@charset 'UTF-8';
a {
color: $primary-color;
cursor: pointer;
text-decoration: none;
word-break: break-word;
color: $color--primary;
}
a:focus,
a:hover {
color: $color--primary--hover;
}
.text-danger,
a.text-danger {
color: #e05f5d;
&:hover,
&:focus {
color: #e05f5d;
color: $primary-color--hover;
}
}
.text-danger {
color: desaturate($red, 20%);
&:hover,
&:focus {
color: desaturate($red, 20%);
}
}

Просмотреть файл

@@ -1,24 +1,24 @@
@charset 'UTF-8';
.mention {
color: #fff;
background: $color--primary;
@include border-radius(3px);
background: $primary-color;
color: $white;
padding-bottom: 2px;
position: relative;
z-index: 10;
padding-bottom: 2px;
@include border-radius(3px);
}
.mentions__name {
position: relative;
width: 100%;
height: 36px;
padding: 2px;
z-index: 101;
line-height: 36px;
font-size: 13px;
cursor: pointer;
font-size: 13px;
height: 36px;
line-height: 36px;
padding: 2px;
position: relative;
white-space: nowrap;
width: 100%;
z-index: 101;
.mention-align {
@include clearfix;
@@ -28,29 +28,29 @@
}
.mention__image {
margin-right: 6px;
height: 32px;
width: 32px;
line-height: 36px;
@include border-radius(32px);
display: block;
font-size: 20px;
height: 32px;
line-height: 36px;
margin-right: 6px;
text-align: center;
@include border-radius(32px);
width: 32px;
.mention--align {
display: inline-block;
max-width: 80%;
overflow: hidden;
display: inline-block;
white-space: nowrap;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.mention__fullname {
color: grey;
color: $dark-gray;
padding-left: 10px;
}
.mention--highlight {
background-color: #fff2bb;
background-color: $yellow;
}

Просмотреть файл

@@ -1,12 +1,24 @@
@charset 'UTF-8';
#channel_members_modal .modal-body {
min-height: 110px;
.browser--ie {
.modal {
.modal-dialog {
@include translateY(0);
}
}
}
.modal-body {
padding: 20px 15px;
overflow: auto;
padding: 20px 15px;
.edit-modal-body {
overflow: visible;
.suggestion-list__content {
max-height: 150px;
}
}
}
.more-table {
@@ -15,27 +27,23 @@
}
.modal {
color: alpha-color($black, .9);
width: 100%;
color: #333;
body.browser--IE & {
.modal-dialog {
@include translateY(0);
}
}
&.image_modal {
.modal-backdrop.in {
@include opacity(.7);
&.modal-image {
.modal-backdrop {
&.in {
@include opacity(.7);
}
}
}
.custom-textarea {
border-color: $light-gray;
color: inherit;
border-color: #ccc;
&:focus {
border-color: #ccc;
border-color: $light-gray;
box-shadow: none;
}
}
@@ -44,15 +52,15 @@
font-size: 13px;
&.btn-default {
border: none;
background: transparent;
border: none;
}
}
.info__label {
font-weight: 600;
text-align: right;
padding-right: 0;
text-align: right;
}
.team-member-list {
@@ -60,21 +68,21 @@
}
.remove__member {
color: $dark-gray;
float: right;
color: #999;
font-size: 20px;
line-height: 0;
padding: 6px;
&:hover {
color: #e56565;
color: $red;
}
}
.modal-dialog {
max-width: 95%;
margin-left: auto;
margin-right: auto;
max-width: 95%;
}
.modal-push-down {
@@ -82,51 +90,51 @@
}
.modal-next-bar {
position: absolute;
top: 0px;
right: 0;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
.modal-header {
border-radius: 0;
background: $color--primary;
color: #fff;
padding: 15px 15px 11px;
border: 1px solid #ddd;
min-height: 56px;
@include border-radius(0);
@include clearfix;
background: $primary-color;
border: 1px solid $light-gray;
color: $white;
min-height: 56px;
padding: 15px 15px 11px;
.modal-title {
color: $bg--gray;
float: left;
font-size: 17px;
line-height: 27px;
color: #f4f4f4;
.name {
color: $white;
font-weight: 600;
color: #fff;
}
}
.modal-action {
padding: 0;
margin: 0;
padding: 0;
}
button.close {
color: #fff;
.close {
@include opacity(1);
z-index: 5;
width: 30px;
@include single-transition(all, .25s, ease-in);
color: $white;
height: 30px;
line-height: 30px;
@include single-transition(all, .25s, ease-in);
position: absolute;
right: 10px;
width: 30px;
z-index: 5;
&:hover {
background: rgba(0, 0, 0, .1);
@include alpha-property(background, $black, .1);
}
span {
@@ -149,8 +157,8 @@
}
.no-channel-message {
text-align: center;
padding: 2em 1em;
text-align: center;
.primary-message {
font-size: 1.25em;
@@ -168,46 +176,46 @@
}
.modal-chevron-icon {
top: 50%;
font-size: 120%;
top: 50%;
}
.modal-prev-bar {
position: absolute;
top: 0px;
left: 0;
height: 100%;
left: 0;
position: absolute;
top: 0;
}
&#more_channels {
&.more-channel__modal {
.modal-body {
padding: 0;
}
}
.modal-image {
position: relative;
width: 100%;
height: 100%;
margin: 0 auto;
max-width: 100%;
position: relative;
width: 100%;
.modal-body {
@include clearfix;
height: 100%;
display: table;
height: 100%;
max-height: 100%;
table-layout: fixed;
width: 100%;
max-height: 100%;
}
.image-wrapper {
position: relative;
max-width: 90%;
.modal-image__wrapper {
@include border-radius(3px);
display: table-cell;
vertical-align: middle;
max-width: 90%;
position: relative;
text-align: center;
vertical-align: middle;
width: 100%;
&:hover {
@@ -215,33 +223,31 @@
}
&.default {
width: 100%;
height: 80%;
width: 100%;
}
audio,
canvas,
progress,
video {
max-width: 100%;
height: auto;
display: block;
height: auto;
max-width: 100%;
}
.modal-close {
background: url('../images/close.png') no-repeat;
@include single-transition(opacity, .6s);
@include background-size(100% 100%);
width: 37px;
@include opacity(0);
background-image: url('../images/close.png');
cursor: pointer;
height: 37px;
position: absolute;
right: -13px;
top: -13px;
@include opacity(0);
-webkit-transition: opacity .6s;
-moz-transition: opacity .6s;
-o-transition: opacity .6s;
transition: opacity .6s;
cursor: pointer;
width: 37px;
z-index: 9999;
&.modal-close--show {
@@ -250,99 +256,109 @@
}
> div {
display: inline-block;
min-height: 100px;
min-width: 320px;
background: #fff;
display: inline-block;
position: relative;
}
&:hover .file-playback__controls.stop {
@include opacity(1);
}
code {
min-height: 130px;
min-width: 330px;
}
pre, code {
display: inline-block;
}
.post-body--code {
max-height: calc(100vh - 80px);
max-width: calc(100vw - 80px);
overflow: auto;
}
img {
max-width: 100%;
max-height: 100%;
max-width: 100%;
}
.spinner.file__loading {
z-index: 2;
position: absolute;
left: 50%;
margin-left: -16px;
top: 50%;
margin-top: -16px;
.spinner {
.file__loading {
left: 50%;
margin-left: -16px;
margin-top: -16px;
position: absolute;
top: 50%;
z-index: 2;
}
}
}
.modal-content {
background: alpha-color($black, 0);
border: none;
box-shadow: none;
background: rgba(0, 0, 0, 0);
width: 100%;
height: 100%;
padding: 0;
border: none;
width: 100%;
}
.image-body {
vertical-align: middle;
.modal-image__body {
display: table-cell;
text-align: center;
height: 100%;
overflow: visible;
padding: 0;
position: relative;
overflow: visible;
text-align: center;
vertical-align: middle;
}
.image-control {
width: 50px;
height: 45px;
background: url('../images/prev.png') left no-repeat;
float: left;
background: url(../images/prev.png) left no-repeat;
top: 50%;
position: relative;
height: 45px;
margin-top: -23px;
position: relative;
top: 50%;
width: 50px;
&.image-next {
background: url('../images/next.png') left no-repeat;
float: right;
background: url(../images/next.png) left no-repeat;
}
}
.loader-image {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
position: absolute;
right: 0;
top: 0;
}
.loader-percent {
position: absolute;
top: 55px;
bottom: 0;
left: 0;
right: 0;
margin: auto;
color: grey;
color: $dark-gray;
height: 20px;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 55px;
}
.modal-button-bar {
position: absolute;
bottom: -40px;
left: 0px;
right: 0px;
background-color: #222;
@include single-transition(opacity, .6s);
@include border-radius(0 0 3px 3px);
@include opacity(0);
-webkit-transition: opacity .6s;
-moz-transition: opacity .6s;
-o-transition: opacity .6s;
transition: opacity .6s;
background-color: $black;
bottom: -40px;
left: 0;
line-height: 40px;
padding: 0 10px;
position: absolute;
right: 0;
&.footer--show {
@include opacity(1);
@@ -356,10 +372,10 @@
}
.text {
vertical-align: middle;
bottom: 0;
color: white;
color: $white;
margin-left: 5px;
vertical-align: middle;
}
.public-link {
@@ -376,11 +392,12 @@
}
.row--invite {
margin-right: 40px;
@include clearfix;
margin-right: 40px;
.col-sm-6 {
padding: 0 0 0 15px;
&:first-child {
padding-left: 0;
}
@@ -389,26 +406,26 @@
.more-modal {
.user-list {
overflow-y: auto;
overflow-x: hidden;
margin-top: 10px;
overflow-x: hidden;
overflow-y: auto;
position: relative;
}
.modal-body {
padding: 10px 0 20px;
overflow-x: hidden;
padding: 10px 0 20px;
}
.filter-row {
margin: 10px 0;
@include clearfix;
margin: 10px 0;
}
.member-count {
margin-top: 5px;
float: right;
@include opacity(.8);
float: right;
margin-top: 5px;
}
.more-purpose {
@@ -416,21 +433,13 @@
}
}
.modal-body.edit-modal-body {
overflow: visible;
.suggestion-list__content {
max-height: 150px;
}
}
.more-modal__list {
overflow: auto;
display: flex;
flex-direction: column;
overflow: auto;
.popover & {
font-size: 0.95em;
font-size: .95em;
.more-modal__row {
padding: 5px 10px;
@@ -442,9 +451,9 @@
}
.more-modal__image {
@include border-radius(60px);
flex-grow: 0;
flex-shrink: 0;
@include border-radius(60px);
margin-right: 8px;
}
@@ -462,33 +471,33 @@
}
.more-modal__name {
font-weight: 600;
font-size: .95em;
white-space: nowrap;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.more-modal__description {
@include opacity(.7);
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.more-modal__row {
border-bottom: 1px solid;
display: flex;
padding: 8px 15px;
border-bottom: 1px solid;
}
p {
@include opacity(.8);
font-size: .9em;
margin: 5px 0;
overflow: hidden;
text-overflow: ellipsis;
@include opacity(.8);
margin: 5px 0;
}
}

Просмотреть файл

@@ -1,18 +1,18 @@
@charset 'UTF-8';
.prompt {
background: #fff;
border: 1px solid #ddd;
padding: 1em 2em 0;
background: $white;
border: 1px solid $light-gray;
margin: 50px auto;
max-width: 90%;
padding: 1em 2em 0;
width: 600px;
.prompt__heading {
display: table;
font-size: em(20px);
line-height: normal;
margin: 1em 0;
display: table;
width: 100%;
> div {
@@ -26,13 +26,13 @@
}
.prompt__allow {
margin: 1em 0;
font-size: em(24px);
margin: 1em 0;
}
.prompt__buttons {
text-align: right;
border-top: 1px solid #ddd;
border-top: 1px solid $dark-gray;
padding: 1.5em 0;
text-align: right;
}
}

Просмотреть файл

@@ -3,32 +3,38 @@
.popover {
@include border-radius($border-rad);
color: #333;
color: lighten($black, 25%);
&.bottom,
&.right,
&.top,
&.left {
> .arrow:after {
border-color: transparent;
> .arrow {
&:after {
border-color: transparent;
}
}
}
.popover-title {
background: rgba(black, .05);
background: alpha-color($black, .05);
padding: 8px 10px;
}
.popover-content {
p:last-child {
margin-bottom: 5px;
p {
&:last-child {
margin-bottom: 5px;
}
}
}
}
.channel-header__info .popover-content {
max-height: 250px;
overflow: auto;
.channel-header__info {
.popover-content {
max-height: 250px;
overflow: auto;
}
}
.user-popover {
@@ -36,32 +42,35 @@
display: inline-block;
}
.code-popover .popover-content {
padding: 5px;
.code-popover {
.popover-content {
padding: 5px;
}
}
.user-popover__image {
margin: 0 0 10px;
@include border-radius(128px);
margin: 0 0 10px;
}
.user-popover__email {
display: block;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
.search-help-popover {
visibility: hidden;
max-width: none;
width: 100%;
top: 36px;
@include single-transition(opacity, .3s, ease-in);
font-size: em(13px);
max-width: none;
top: 36px;
visibility: hidden;
width: 100%;
&.autocomplete {
display: block;
.popover-content {
padding: 10px;
position: relative;
@@ -69,65 +78,68 @@
}
.search-autocomplete__divider {
margin: 10px 0 5px;
line-height: 21px;
margin: 10px 0 5px;
position: relative;
&:first-child {
margin-top: 5px;
}
span {
> span {
background: $white;
display: inline-block;
padding-right: 10px;
background: #fff;
z-index: 5;
position: relative;
z-index: 5;
}
&:before {
content: '';
position: absolute;
width: 100%;
height: 1px;
background: #ddd;
top: 10px;
left: 0;
@include opacity(.2);
background: $dark-gray;
content: '';
height: 1px;
left: 0;
position: absolute;
top: 10px;
width: 100%;
}
}
.search-autocomplete__item {
cursor: pointer;
padding: 6px 8px;
margin: 3px 0 0 5px;
@include border-radius(2px);
white-space: nowrap;
cursor: pointer;
margin: 3px 0 0 5px;
overflow: hidden;
padding: 6px 8px;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
background: rgba(black, .1);
background: alpha-color($black, .1);
}
&.selected {
background: rgba(black, .2);
background: alpha-color($black, .2);
}
.fa {
margin-right: 5px;
@include opacity(.5);
margin-right: 5px;
}
.profile-img {
margin-top: -1px;
height: 16px;
margin-right: 6px;
margin-top: -1px;
width: 16px;
}
}
&.bottom > .arrow {
top: -18px;
border-width: 9px;
left: 30px;
top: -18px;
}
.popover-content {
@@ -142,9 +154,11 @@
ul {
padding-left: 17px;
span {
@include opacity(.8);
}
strong,
b {
@include opacity(1);
@@ -156,25 +170,28 @@
}
&.visible {
visibility: visible;
@include opacity(1);
visibility: visible;
}
}
#member-list-popover {
.member-list__popover {
max-width: initial;
.popover-content {
position: relative;
padding: 0;
width: 260px;
max-height: 350px;
padding: 0;
position: relative;
width: 260px;
.text-nowrap {
font-size: 13px;
line-height: 26px;
overflow: hidden;
padding: 6px 10px;
width: 100%;
overflow: hidden;
line-height: 26px;
font-size: 13px;
}
.more__name {
margin-left: 6px;
max-width: 140px;

Просмотреть файл

@@ -1,28 +1,25 @@
@charset 'UTF-8';
::-webkit-scrollbar
{
width: 8px; /* for vertical scrollbars */
height: 8px; /* for horizontal scrollbars */
::-webkit-scrollbar {
height: 8px; // for horizontal scrollbars
width: 8px; // for vertical scrollbars
}
::-webkit-scrollbar-track
{
background: rgba(0, 0, 0, 0.1);
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, .1);
}
::-webkit-scrollbar-thumb
{
::-webkit-scrollbar-thumb {
@include border-radius($border-rad * 2);
background: rgba(0, 0, 0, 0.4);
background: rgba(0, 0, 0, .4);
}
body{
scrollbar-face-color: rgba(0, 0, 0, 0.1);
scrollbar-shadow-color: #2D2C4D;
scrollbar-highlight-color:#7D7E94;
body {
scrollbar-3dlight-color: #7D7E94;
scrollbar-darkshadow-color: #2D2C4D;
scrollbar-track-color: rgba(0, 0, 0, 0.1);
scrollbar-arrow-color: #C1C1D1;
scrollbar-darkshadow-color: #2D2C4D;
scrollbar-face-color: rgba(0, 0, 0, .1);
scrollbar-highlight-color: #7D7E94;
scrollbar-shadow-color: #2D2C4D;
scrollbar-track-color: rgba(0, 0, 0, .1);
}

Просмотреть файл

@@ -1,15 +1,19 @@
@charset 'UTF-8';
#channel-header .search-bar__container {
padding: 0 9px 0 3px;
.channel-header {
.search-bar__container {
padding: 0 9px 0 3px;
}
}
.search-bar__container {
padding: 12px 8px 0 0;
@include flex(0 0 56px);
padding: 12px 8px 0 0;
.sidebar--right.move--left & {
padding-right: 42px;
.sidebar--right {
&.move--left & {
padding-right: 42px;
}
}
}
@@ -18,62 +22,60 @@
}
.search__clear {
display: none;
position: absolute;
right: 0;
line-height: 45px;
margin-right: 13px;
@include single-transition(all, .2s, linear);
@include translateX(60px);
z-index: 5;
cursor: pointer;
display: none;
line-height: 45px;
margin-right: 13px;
position: absolute;
right: 0;
z-index: 5;
}
.search-item-snippet {
@include clearfix;
text-overflow: ellipsis;
}
.sidebar__collapse {
cursor: pointer;
z-index: 5;
fill: #fff;
position: absolute;
left: 0;
font-size: 35px;
width: 49px;
@include single-transition(all, .2s, linear);
@include translateX(0px);
text-align: center;
padding-left: 1px;
line-height: 40px;
display: none;
}
.search-item-snippet {
ul,
ol {
padding-left: 20px;
}
}
.sidebar__collapse {
@include single-transition(all, .2s, linear);
@include translateX(0);
cursor: pointer;
display: none;
fill: $white;
font-size: 35px;
left: 0;
line-height: 40px;
padding-left: 1px;
position: absolute;
text-align: center;
width: 49px;
z-index: 5;
}
.sidebar__search-icon {
@include opacity(.5);
color: $dark-gray;
display: none;
font-size: 14px;
margin-left: 10px;
position: absolute;
top: 15px;
margin-left: 10px;
font-size: 14px;
@include opacity(.5);
display: none;
color: #777;
}
.search__form {
position: relative;
.search-bar__container & {
margin: 0;
border: 1px solid #ddd;
@include border-radius(2px);
border: 1px solid $light-gray;
margin: 0;
width: 300px;
}
@@ -82,21 +84,21 @@
}
.search-bar {
box-shadow: none;
height: 40px;
padding-right: 30px;
box-shadow: none;
.search-bar__container & {
height: 30px;
border: none;
height: 30px;
}
}
.glyphicon-refresh-animate {
top: 27px;
color: $dark-gray;
position: absolute;
right: 27px;
color: #999;
top: 27px;
.search-bar__container & {
right: 7px;
@@ -106,30 +108,29 @@
}
.search-items-container {
position: relative;
overflow: auto;
-webkit-overflow-scrolling: touch;
@include flex(1 1 auto);
-webkit-overflow-scrolling: touch;
height: calc(100% - 56px);
overflow: auto;
padding-top: 10px;
position: relative;
}
.search-results-header {
border-bottom: $border-gray;
color: #999999;
font-size: 1em;
text-transform: uppercase;
color: #999;
font-weight: 400;
color: #888;
height: 44px;
line-height: 44px;
padding: 0 10px 0 10px;
border-bottom: $border-gray;
padding: 0 10px;
text-transform: uppercase;
}
.search-item__container {
.post {
padding: 0 1em 1em;
margin: 0;
padding: 0 1em 1em;
&:first-child {
border: none;
@@ -137,17 +138,17 @@
.search-channel__name {
font-weight: 600;
margin: 0 0 10px 0;
margin: 0 0 10px;
}
}
}
.search-item__jump {
@include opacity(.8);
font-size: 13px;
position: absolute;
right: 0;
top: 0px;
font-size: 13px;
@include opacity(.8);
top: 0;
&:hover {
@include opacity(1);
@@ -155,9 +156,9 @@
}
.search-item__comment {
margin-right: 35px;
position: absolute;
right: 0;
margin-right: 35px;
top: 0;
}
@@ -171,5 +172,5 @@
}
.search-highlight {
background-color: #fff2bb;
background-color: $yellow;
}

Просмотреть файл

@@ -1,9 +1,9 @@
@charset 'UTF-8';
.suggestion-list {
@extend %popover-box-shadow;
width: 100%;
z-index: 100;
@extend %popover-box-shadow;
}
.suggestion-list--top {
@@ -11,31 +11,31 @@
}
.suggestion-list__content {
width: 100%;
max-height: 292px;
background-color: #fff;
background-color: $white;
border: $border-gray;
max-height: 292px;
overflow-x: hidden;
overflow-y: scroll;
width: 100%;
.command {
position: relative;
width: 100%;
border-bottom: 1px solid $light-gray;
font-size: .95em;
line-height: 24px;
padding: 5px 10px 8px;
position: relative;
width: 100%;
z-index: 101;
font-size: .95em;
border-bottom: 1px solid #ddd;
.command__desc {
margin-left: 5px;
@include opacity(.5);
line-height: normal;
margin-left: 5px;
}
}
}
.suggestion-list__content--top {
position: absolute;
bottom: 0;
position: absolute;
}

Просмотреть файл

@@ -2,9 +2,9 @@
.tooltip {
.tooltip-inner {
word-break: break-word;
font-size: 13px;
padding: 3px 10px 4px;
font-weight: 500;
padding: 3px 10px 4px;
word-break: break-word;
}
}

Просмотреть файл

@@ -1,72 +1,76 @@
@charset 'UTF-8';
.tip-backdrop {
background: rgba(black, .5);
background: alpha-color($black, .5);
height: 100%;
left: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}
.tip-overlay {
width: 350px;
max-width: 90%;
position: absolute;
background-color: #fff;
@include border-radius(3px);
background-color: $white;
max-width: 90%;
padding: 20px;
position: absolute;
width: 350px;
z-index: 1000;
.arrow {
border-width: 10px;
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 10px;
display: block;
height: 0;
position: absolute;
width: 0;
}
&.tip-overlay--sidebar {
max-width: 75%;
margin: 50px 0 0 10px;
max-width: 75%;
min-height: 330px;
.tutorial__footer {
position: absolute;
width: 100%;
bottom: 20px;
left: 0;
padding: 0 20px;
position: absolute;
width: 100%;
}
.arrow {
top: 80px;
border-left-width: 0;
border-right-color: $white;
left: -10px;
margin-top: -10px;
border-left-width: 0;
border-right-color: #fff;
top: 80px;
}
}
&.tip-overlay--header {
margin: 10px 0 0 10px;
.arrow {
top: 15px;
left: -10px;
border-left-width: 0;
border-right-color: #fff;
border-right-color: $white;
left: -10px;
top: 15px;
}
}
&.tip-overlay--chat {
margin-top: -10px;
.arrow {
border-bottom-width: 0;
border-top-color: $white;
bottom: -10px;
left: 50%;
margin-left: -10px;
border-bottom-width: 0;
border-top-color: #fff;
bottom: -10px;
}
}
@@ -86,18 +90,18 @@
}
.btn {
background: #ccc;
color: #fff;
@include border-radius(3px);
background: alpha-color($black, .3);
border: none;
color: $white;
margin: 10px 0;
&:hover,
&:active,
&:focus {
color: #fff;
background: alpha-color($black, .4);
border: none;
background: #bbb;
color: $white;
}
}
@@ -110,81 +114,88 @@
}
.tutorial__circles {
margin: 1.5em 0px -1.7em -4px;
margin: 1.5em 0 -1.7em -4px;
.circle {
width: 7px;
height: 7px;
margin: 0 4px;
width: 7px;
}
}
}
.tip-button {
z-index: 998;
cursor: pointer;
position: relative;
right: -10px;
top: -10px;
position: relative;
cursor: pointer;
z-index: 998;
}
.tip-div {
position: absolute;
top: 0px;
right: 0px;
right: 0;
top: 0;
&.tip-overlay--header {
top: 21px;
right: 2px;
top: 21px;
.tip-button {
@include opacity(.8);
}
}
&.tip-overlay--sidebar {
left: 0;
@include opacity(.8);
left: 0;
top: -9px;
}
}
.tutorial-steps__container {
text-align: center;
width: 100%;
display: table;
height: 100%;
text-align: center;
width: 100%;
.tutorial__content {
display: table-cell;
vertical-align: middle;
padding-bottom: 100px;
padding: 20px 40px 40px;
vertical-align: middle;
.tutorial__steps {
position: relative;
display: inline-block;
margin-bottom: 50px;
max-width: 310px;
min-height: 370px;
margin-bottom: 50px;
position: relative;
text-align: left;
display: inline-block;
}
}
.tutorial__footer {
position: absolute;
bottom: 0;
position: absolute;
}
h1 {
font-size: em(40px);
margin: -20px 0 30px;
font-weight: 600;
margin: -20px 0 30px;
}
h3 {
font-size: em(24px);
margin-bottom: 30px;
font-weight: 600;
margin-bottom: 30px;
}
.tutorial__circles {
position: absolute;
bottom: 40px;
position: absolute;
}
.tutorial-skip {
margin-left: 13px;
}
@@ -192,17 +203,19 @@
.tutorial__circles {
margin: 2em 0;
.circle {
width: 9px;
height: 9px;
@include border-radius(9px);
@include opacity(.2);
background: #000;
background: $black;
display: inline-block;
height: 9px;
margin: 0 5px;
width: 9px;
&.active {
background: $color--primary;
@include opacity(1);
background: $primary-color;
}
}
}

Просмотреть файл

@@ -1,65 +1,68 @@
@charset 'UTF-8';
.video-div {
position: relative;
max-width: 480px;
margin-bottom: 8px;
max-width: 480px;
position: relative;
.video-thumbnail {
max-width: 100%;
height: auto;
max-width: 100%;
}
.block {
background-color: rgba(0,0,0,.5);
background-color: alpha-color($black, .5);
border-radius: 10px;
height: 150px;
left: 50%;
margin: -75px 0 0 -100px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -100px;
width: 200px;
margin: -75px 0 0 -100px;
height: 150px;
}
}
.video-type {
@include opacity(.8);
font-size: 15px;
margin: 0px;
padding: 0px;
margin: 0;
padding: 0;
}
.video-title {
font-size: 15px;
margin-top: 3px;
}
.play-button {
width: 100px;
@include border-radius(14px);
border: 4px solid alpha-color($white, .4);
height: 100px;
position: absolute;
top: 26px;
right: 51px;
border: 4px solid;
border-color: rgba(255,255,255,.4);
border-radius: 14px;
}
.play-button span {
position: absolute;
top: 10px;
left: 20px;
width: 0;
height: 0;
border-top: 36px solid transparent;
border-bottom: 36px solid transparent;
border-left: 60px solid rgba(255,255,255,.4);
top: 26px;
width: 100px;
span {
border-bottom: 36px solid transparent;
border-left: 60px solid alpha-color($white, .4);
border-top: 36px solid transparent;
height: 0;
left: 20px;
position: absolute;
top: 10px;
width: 0;
}
}
.img-div {
-moz-force-broken-image-icon: 1;
position: relative;
max-width: 450px;
max-height: 500px;
margin-bottom: 8px;
border-radius: 5px;
margin-bottom: 8px;
max-height: 500px;
max-width: 450px;
position: relative;
&.placeholder {
height: 500px;
}

Просмотреть файл

@@ -15,21 +15,22 @@
}
.app__content {
height: 100%;
padding-top: 50px;
margin-left: 220px;
position: relative;
background: #fff;
@include display-flex;
@include flex-direction(column);
background: $white;
height: 100%;
margin-left: 220px;
padding-top: 50px;
position: relative;
.channel__wrap & {
padding-top: 0;
}
}
#post-create {
@include flex(0 0 auto);
background: #fff;
background: $white;
width: 100%;
z-index: 3;
}
@@ -37,12 +38,12 @@
#archive-link-home {
@include flex(0 0 auto);
cursor: pointer;
padding: 10px 20px;
font-size: 13px;
padding: 10px 20px;
.fa {
font-size: 11px;
@include opacity(.7);
font-size: 11px;
}
a {
@@ -50,36 +51,6 @@
}
}
.post-list {
.new-messages-hr {
margin-top: 5px;
margin-bottom: 0px;
border: 0;
border-top: 1px solid #f80;
}
.new-messages-text {
margin-top: 2px;
margin-bottom: 5px;
color: #f80;
text-align: center;
}
}
.new-messages-hr {
margin-top: 5px;
margin-bottom: 0px;
border: 0;
border-top: 1px solid #f80;
}
.new-messages-text {
margin-top: 2px;
margin-bottom: 5px;
color: #f80;
text-align: center;
}
.delete-message-text {
margin-top: 10px;
}

Просмотреть файл

@@ -1,22 +1,22 @@
@charset 'UTF-8';
.footer-pane {
background: #eee;
background: $light-gray;
padding-bottom: 1em;
.footer-link {
padding: 0 1.5em;
&.copyright {
color: #999;
color: $dark-gray;
padding-right: 0;
}
}
.footer-site-name {
padding: 1.5em 0 1em;
font-size: 14px;
font-weight: bold;
padding: 1.5em 0 1em;
text-transform: uppercase;
}
}

Просмотреть файл

@@ -6,32 +6,32 @@
}
.form__label {
text-align: left;
padding-right: 3px;
font-weight: 600;
font-size: 1.1em;
font-weight: 600;
padding-right: 3px;
text-align: left;
&.light {
font-weight: normal;
color: #999;
color: $dark-gray;
font-size: 1.05em;
font-style: italic;
font-weight: normal;
padding-top: 2px;
}
}
.input__help {
@include opacity(.8);
color: inherit;
margin: 10px 0 0 10px;
word-break: break-word;
@include opacity(.8);
&.dark {
@include opacity(1);
}
&.error {
color: #a94442;
color: darken($red, 20%);
}
}
@@ -49,13 +49,9 @@
}
.help-block {
color: $dark-gray;
font-size: .95em;
margin: 10px 0 0;
color: #999;
}
.disabled-input {
background-color: #ddd !important;
}
.form-group {

Просмотреть файл

@@ -1,6 +1,6 @@
@charset 'UTF-8';
#channel-header {
.channel-header {
@include flex(0 0 56px);
}
@@ -15,8 +15,8 @@
}
.header-dropdown__icon {
font-size: 11px;
color: inherit;
font-size: 11px;
top: 3px;
}
@@ -31,12 +31,12 @@
word-break: break-word;
&.dropdown {
float: left;
max-width: 100%;
padding-right: 1em;
float: left;
.header-dropdown__icon {
color: #777;
color: $dark-gray;
}
a {
@@ -49,10 +49,11 @@
}
&.description {
overflow: hidden;
text-overflow: ellipsis;
margin-top: 2px;
max-height: 45px;
overflow: hidden;
text-overflow: ellipsis;
.markdown-inline-img {
max-height: 45px;
}
@@ -65,14 +66,14 @@
}
.channel-intro {
border-bottom: 1px solid $light-gray;
margin: 0 auto 35px;
padding: 0 1em 5px;
max-width: 1000px;
border-bottom: 1px solid lightgrey;
padding: 0 1em 5px;
.intro-links {
margin: 0 1.5em 10px 0;
display: inline-block;
margin: 0 1.5em 10px 0;
.fa {
margin-right: 5px;
@@ -80,28 +81,30 @@
}
.channel-intro-profile {
margin-top: 5px;
margin-left: 63px;
margin-top: 5px;
}
.channel-intro-img {
float: left;
img {
@include border-radius(100px);
}
}
.channel-intro__title {
font-weight: 600;
font-size: 20px;
font-weight: 600;
margin-bottom: 15px;
}
.channel-intro__content {
background: #f7f7f7;
padding: 10px 15px;
@include border-radius(3px);
background: $bg--gray;
padding: 10px 15px;
}
.channel-intro-text {
margin-top: 35px;
}
@@ -111,28 +114,28 @@
.sidebar--left,
.sidebar--menu {
.team__header {
position: relative;
padding: 9px 10px;
@include legacy-pie-clearfix;
padding: 9px 10px;
position: relative;
&:before {
@include single-transition(all, .05s, linear);
content: '';
background: none;
top: 0;
left: 0;
width: 100%;
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
&:hover {
&:before {
background: rgba(black, .1);
@include alpha-property(background, $black, .1);
}
.user__name {
color: #fff;
color: $white;
}
.navbar-right {
@@ -145,95 +148,88 @@
.navbar-right {
font-size: .85em;
position: absolute;
top: 10px;
right: 22px;
top: 10px;
z-index: 5;
.dropdown-toggle {
@include opacity(.8);
@include single-transition(all, .1s, linear);
padding: 10px;
@include opacity(.8);
}
.dropdown-menu {
li a {
a {
overflow: hidden;
padding: 3px 20px;
text-overflow: ellipsis;
overflow: hidden;
}
}
.dropdown__icon {
fill: #fff;
fill: $white;
}
}
.settings__link a:hover,
a:visited,
a:link,
a:active {
text-decoration: none;
}
.user__picture {
width: 36px;
height: 36px;
float: left;
@include border-radius(36px);
float: left;
height: 36px;
margin-right: 6px;
width: 36px;
}
.header__info {
color: #fff;
@include clearfix;
color: $white;
padding-left: 2px;
z-index: 1;
position: relative;
z-index: 1;
}
.team__name,
.user__name {
display: block;
font-weight: 600;
font-size: 16px;
font-weight: 600;
max-width: 85%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
.team__name {
float: left;
line-height: 22px;
margin-top: -2px;
float: left;
}
.user__name {
@include single-transition(all, .1s, linear);
@include alpha-property(color, $white, .8);
font-size: 14px;
line-height: 18px;
font-weight: 400;
color: #eee;
color: rgba(#fff, .8);
line-height: 18px;
}
> .nav {
> li {
> a {
background: none;
float: right;
background: none !important;
padding: 2px;
}
&.dropdown-toggle {
line-height: 1.8;
font-size: 1em;
color: #fff;
}
.dropdown-toggle {
color: $white;
font-size: 1em;
line-height: 1.8;
}
}
}
}
.search__clear {
display: none;
}
@@ -250,27 +246,29 @@
}
.channel-header {
width: 100%;
border-left: none;
font-size: 14px;
line-height: 56px;
width: 100%;
#member_popover {
width: 50px;
color: #999;
color: #999999;
cursor: pointer;
width: 50px;
.fa {
margin-left: 4px;
font-size: 16px;
margin-left: 4px;
}
}
&.alt {
margin: 0;
th {
font-weight: normal !important;
}
td {
border: none;
}
@@ -278,37 +276,39 @@
th {
text-align: center;
&:first-child {
text-align: left !important;
border-left: none;
width: 100%;
padding-left: 1em;
text-align: left !important;
width: 100%;
}
&:last-child {
width: 8.9%;
}
}
td {
padding: 5px 25px 5px !important;
font-size: 13px;
padding: 5px 25px 5px !important;
text-align: center !important;
&:first-child {
text-align: left !important;
}
}
.heading {
margin: 0;
color: #555;
color: #555555;
display: inline-block;
font-size: 1.3em;
font-weight: 600;
margin: 0 4px 0 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
display: inline-block;
vertical-align: middle;
margin-right: 4px;
}
.caret {
@@ -318,13 +318,13 @@
.more {
color: #81848b;
display: inline-block;
vertical-align: top;
text-transform: capitalize;
font-size: 13px;
text-transform: capitalize;
vertical-align: top;
}
.disabled {
color: #999;
color: #999999;
}
}
@@ -342,11 +342,11 @@
.channel-header__links {
font-family: 'Open Sans', sans-serif;
font-size: 22px;
height: 30px;
width: 24px;
line-height: 26px;
margin-right: 9px;
font-size: 22px;
width: 24px;
.channel__wrap.move--left & {
position: absolute;
@@ -355,14 +355,15 @@
}
> a {
color: inherit;
text-decoration: none;
@include opacity(.6);
@include single-transition(all, .1s, ease-in);
color: inherit;
text-decoration: none;
&:hover {
@include opacity(1);
}
&:focus {
color: inherit;
}

Просмотреть файл

@@ -16,43 +16,77 @@
#post-list {
.markdown-inline-img {
-moz-force-broken-image-icon: 1;
max-height: 500px;
height: 500px;
max-height: 500px;
}
}
.post-body--code {
overflow-x: auto;
overflow-y: hidden;
position: relative;
pre {
margin-bottom: 0;
word-break: normal;
overflow: auto;
word-wrap: normal;
border: 1px solid rgba(221,221,221,0.2);
border-radius: .25em;
margin: 0;
padding: 0px;
text-align: left;
white-space: nowrap;
}
code {
border: none;
white-space: pre;
}
td {
padding: 0 .5em;
vertical-align: top;
}
&:hover .post-body--code__language {
@include opacity(1);
}
}
.post-body--code__language {
-webkit-transform: translate3d(0,0,0);
position: absolute;
top: 0;
right: 0;
color: #fff;
@include opacity(0);
@include translate3d(0, 0, 0);
background: #21586d;
padding: 4px 10px 5px 10px;
font-size: 13px;
opacity: .7;
border-radius: 0 .25em;
color: $white;
padding: 4px 10px 5px;
position: absolute;
right: 0;
top: 0;
-webkit-transition: opacity 0.6s;
-moz-transition: opacity 0.6s;
-o-transition: opacity 0.6s;
transition: opacity 0.6s;
z-index: 5;
}
.post-body--code__lineno {
border-right: 1px solid #aaa;
color: #aaa;
margin-right: .5em;
text-align: right;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.post__body {
hr {
height: 4px;
padding: 0;
margin: 15px 0 16px;
@include opacity(.2);
background-color: #e7e7e7;
border: 0 none;
@include opacity(.2);
height: 4px;
margin: 15px 0 16px;
padding: 0;
}
code {
@@ -67,50 +101,53 @@
}
.markdown__table {
background: #fff;
background: $white;
margin: 5px 0 10px;
th,
td {
padding: 6px 13px;
border: 1px solid #ddd;
padding: 6px 13px;
}
tbody tr {
background: #fff;
background: $white;
&:nth-child(2n) {
background-color: #f8f8f8;
}
}
}
blockquote {
border: none;
position: relative;
font-size: 16px;
padding: 10px 10px 10px 38px;
margin-bottom: 0;
padding: 10px 10px 10px 38px;
position: relative;
&:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
content: '\f10d';
left: 8px;
top: 5px;
position: absolute;
font-size: 20px;
@include opacity(.6);
content: '\f10d';
display: inline-block;
font-family: FontAwesome;
font-size: 20px;
font-style: normal;
font-weight: normal;
left: 8px;
position: absolute;
text-decoration: inherit;
top: 5px;
}
}
pre {
border: none;
color: inherit;
margin: 5px 0;
color: inherit;
padding: 0;
}
code {
background: #fff;
background: $white;
color: inherit;
}

Просмотреть файл

@@ -7,14 +7,14 @@
#navbar {
input {
margin: 0px 5px 0px 2px;
margin: 0 5px 0 2px;
}
.navbar-default {
position: absolute;
background: $primary-color;
border: none;
min-height: 45px;
background: $color--primary;
position: absolute;
.navbar-nav {
> li {
@@ -30,19 +30,19 @@
}
.navbar-toggle {
width: 43px;
float: left;
border-color: transparent;
border-radius: 0;
fill: $white;
float: left;
height: 44px;
line-height: 48px;
margin: 0;
padding: 0 10px;
line-height: 48px;
height: 44px;
width: 43px;
z-index: 5;
fill: #fff;
.icon-bar {
background: #fff;
background: $white;
width: 21px;
}
@@ -51,7 +51,7 @@
}
.icon--white {
color: #fff;
color: $white;
}
&:hover,
@@ -62,16 +62,16 @@
}
.navbar-brand {
padding: 0 .5em;
height: 45px;
line-height: 45px;
float: none;
font-size: 16px;
height: 45px;
line-height: 45px;
padding: 0 .5em;
.heading {
margin-right: 3px;
color: $white;
font-weight: 600;
color: #fff;
margin-right: 3px;
}
.header-dropdown__icon {
@@ -79,36 +79,36 @@
}
.dropdown-toggle {
color: #fff;
color: $white;
}
.description {
color: $white;
display: inline-block;
margin-right: .5em;
color: #fff;
&.info-popover {
width: 19px;
height: 19px;
background: url('../images/info__icon.png');
@include background-size(100% 100%);
vertical-align: middle;
top: -1px;
position: relative;
background: url('../images/info__icon.png');
cursor: pointer;
height: 19px;
position: relative;
top: -1px;
vertical-align: middle;
width: 19px;
}
}
}
}
.sidebar-channel {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
span {
white-space: nowrap;
margin-left: 2px;
white-space: nowrap;
}
}
@@ -117,11 +117,13 @@
}
.more-channel-table {
width: 100%;
border: 1px solid #dbdbdc;
width: 100%;
td {
padding: 7px;
}
button {
width: 110px;
}
@@ -129,9 +131,9 @@
}
.badge-notify {
background: red;
position: absolute;
background: $red;
left: 4px;
position: absolute;
top: 3px;
z-index: 100;
}

Просмотреть файл

@@ -27,8 +27,8 @@
.post {
&.post--root {
padding-bottom: 1.2em;
border-bottom: 1px solid #ddd;
padding-bottom: 1.2em;
.post__body {
background: transparent !important;
@@ -37,8 +37,8 @@
.post__header {
.col__reply {
top: 0;
text-align: right;
top: 0;
}
}
@@ -48,13 +48,13 @@
}
hr {
margin-bottom: 0;
border: none;
margin-bottom: 0;
}
.post-create__container {
width: 100%;
margin-top: 10px;
width: 100%;
.textarea-wrapper {
min-height: 100px;
@@ -70,48 +70,46 @@
.msg-typing {
@include opacity(.7);
float: left;
margin-top: 3px;
font-size: 13px;
line-height: 20px;
min-width: 1px;
display: block;
float: left;
font-size: 13px;
height: 20px;
line-height: 20px;
margin-top: 3px;
max-width: 230px;
min-width: 1px;
}
.post-create-footer {
width: 100%;
padding: 5px 0 10px;
width: 100%;
}
.post-right-comments-upload-in-progress {
padding: 6px 0;
color: #a8adb7;
margin-right: 10px;
padding: 6px 0;
}
}
}
.post-right-header {
font-size: 1em;
text-transform: uppercase;
border-bottom: $border-gray;
color: #999;
font-size: 1em;
font-weight: 400;
color: #888;
height: 39px;
padding: 10px 10px 0 15px;
border-bottom: $border-gray;
text-transform: uppercase;
}
.post-right-root-container {
border-bottom: $border-gray;
padding: 5px 10px;
border-bottom: $border-gray;
}
.post-right-root-container {
ul {
padding-left: 0;
margin-bottom: 2px;
padding-left: 0;
}
}
@@ -131,19 +129,19 @@
}
.post-right-create-comment-container {
padding: 5px;
margin-bottom: 18px;
position: absolute;
bottom: 0;
left: 0;
margin-bottom: 18px;
padding: 5px;
position: absolute;
width: 100%;
}
.post-right__scroll {
position: relative;
overflow: auto;
-webkit-overflow-scrolling: touch;
@include flex(1 1 auto);
-webkit-overflow-scrolling: touch;
overflow: auto;
position: relative;
.file-preview__container {
margin-top: 5px;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@@ -1,86 +1,97 @@
@charset 'UTF-8';
.sidebar--left {
background: #fafafa;
border-right: $border-gray;
height: 100%;
left: 0;
position: absolute;
width: 220px;
left: 0;
height: 100%;
border-right: $border-gray;
background: #fafafa;
z-index: 5;
&.sidebar--padded {
padding-top: 44px;
}
.dropdown-menu {
max-height: 400px;
max-width: 200px;
overflow-x: hidden;
overflow-y: auto;
max-width: 200px;
width: 200px;
}
.search__form {
display: none;
margin: 0;
padding: 1em 1em 0;
display: none;
}
.badge {
background-color: $color--primary;
background-color: $primary-color;
position: absolute;
right: 10px;
top: 5px;
}
.status {
display: inline-block;
margin-right: 6px;
position: relative;
top: 1px;
margin-right: 6px;
width: 12px;
display: inline-block;
svg {
max-height: 14px;
}
i,
path,
ellipse {
@include opacity(.5);
&.online--icon,
&.away--icon {
@include opacity(1);
}
}
.fa-lock {
margin-left: 1px;
}
.fa-globe {
top: -1px;
position: relative;
top: -1px;
}
}
.nav-pills__container {
height: calc(100% - 80px);
position: relative;
overflow: auto;
-webkit-overflow-scrolling: touch;
height: calc(100% - 80px);
overflow: auto;
position: relative;
}
.nav-pills__unread-indicator {
position: absolute;
left: 0;
right: 0;
width: 72%;
color: #fff;
background: #2389d7;
@include border-radius(50px);
background: #2389d7;
color: #ffffff;
font-size: 13.5px;
left: 0;
margin: 0 auto;
padding: 3px 0 4px;
font-size: 13.5px;
position: absolute;
right: 0;
text-align: center;
width: 72%;
z-index: 1;
}
.nav-pills__unread-indicator-top {
top: 66px;
}
.nav-pills__unread-indicator-bottom {
bottom: 20px;
}
@@ -91,71 +102,83 @@
margin: 0;
}
}
li {
> h4 {
color: #aaaaaa;
font-size: 1em;
text-transform: uppercase;
margin: 1.1em 0 .5em;
font-weight: 400;
color: #aaa;
letter-spacing: -.3px;
margin: 1.1em 0 .5em;
padding: 0 10px 0 15px;
text-transform: uppercase;
}
> a {
padding: 3px 10px 3px 25px;
line-height: 1.5;
border-radius: 0;
white-space: nowrap;
line-height: 1.5;
overflow: hidden;
padding: 3px 10px 3px 25px;
text-overflow: ellipsis;
white-space: nowrap;
&.has-badge {
padding-right: 30px;
}
&.has-close {
padding-right: 30px;
&:hover {
.btn-close {
display: block;
@include opacity(.8);
display: block;
}
}
.btn-close {
@include opacity(0);
display: none;
font-family: 'Open Sans', sans-serif;
font-size: 20px;
font-weight: 600;
position: absolute;
right: 15px;
top: -1px;
font-size: 20px;
font-weight: 600;
@include opacity(0);
display: none;
&:hover {
@include opacity(1);
}
}
}
&.nav-more {
text-decoration: underline;
}
&.unread-title {
font-weight: 600;
}
}
&.active {
a {
&:before {
background: $black;
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
left: 0;
width: 5px;
height: 100%;
background: #000;
}
}
a,
a:hover,
a:focus {
background-color: rgba(black, .1);
@include alpha-property(background-color, $black, .1);
border-radius: 0;
font-weight: 400;
position: relative;
@@ -163,35 +186,37 @@
}
}
}
.modal-title {
line-height: 2em;
}
.add-channel-btn {
color: #aaaaaa;
float: right;
outline: none;
font-size: 22px;
font-weight: 700;
line-height: 18px;
margin: -2px 0 0 0;
color: #aaa;
outline: none;
padding: 0 5px;
text-decoration: none;
font-size: 22px;
line-height: 18px;
font-weight: 700;
&:hover {
color: #666;
color: #666666;
}
}
}
.channel-loading-gif {
height: 15px;
width: 15px;
margin-top: 2px;
width: 15px;
}
.join-channel-loading-gif {
margin-top: 5px;
margin-left: 10px;
height: 25px;
margin-left: 10px;
margin-top: 5px;
width: 25px;
}

Просмотреть файл

@@ -1,69 +1,79 @@
@charset 'UTF-8';
.sidebar--menu {
position: absolute;
width: 220px;
right: 0;
height: 100%;
border-right: $border-gray;
padding: 0 0 2em 0;
background: #fafafa;
border-right: $border-gray;
display: none;
height: 100%;
padding: 0 0 2em;
position: absolute;
right: 0;
width: 220px;
.nav-pills__container {
padding-top: 5px;
}
.team__header {
@include legacy-pie-clearfix;
display: none;
padding: 0 15px;
@include legacy-pie-clearfix;
a {
color: #fff;
color: $white;
}
.navbar-right {
font-size: .85em;
margin: 16px -5px 0;
.dropdown-toggle {
padding: 0 10px;
}
.dropdown-menu {
li a {
padding: 3 20px;
color: #555;
padding: 3 20px;
}
}
.dropdown__icon {
width: 4px;
height: 16px;
@include background-size(100% 100%);
display: inline-block;
height: 16px;
width: 4px;
}
}
.team__name {
float: left;
line-height: 50px;
font-weight: 600;
font-size: 1.2em;
font-weight: 600;
line-height: 50px;
max-width: 80%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.nav {
> li {
> a {
font-size: 15px;
background: none !important;
color: inherit;
font-size: 15px;
line-height: 40px;
padding: 0 15px;
.fa,
.glyphicon {
width: 25px;
text-align: center;
left: -5px;
position: relative;
text-align: center;
width: 25px;
}
}
}

Просмотреть файл

@@ -1,13 +1,13 @@
@charset 'UTF-8';
.sidebar--right {
position: fixed;
width: 400px;
height: 100%;
right: 0px;
padding: 0;
background: #fff;
@include translateX(400px);
background: $white;
height: 100%;
padding: 0;
position: fixed;
right: 0;
width: 400px;
.post-body {
img {
@@ -26,39 +26,39 @@
}
.sidebar--right__content {
height: 100%;
@include display-flex;
@include flex-direction(column);
height: 100%;
}
.sidebar--right__back {
color: inherit;
@include opacity(.8);
width: 30px;
text-align: center;
margin: 0 0 0 -14px;
font-size: 13px;
color: inherit;
display: inline-block;
font-size: 13px;
margin: 0 0 0 -14px;
text-align: center;
width: 30px;
}
.sidebar-right__body {
@include border-radius(2px 0 0 0);
@include display-flex;
@include flex(1 1 auto);
@include flex-direction(column);
border-left: $border-gray;
border-top: $border-gray;
@include display-flex;
@include flex-direction(column);
height: calc(100% - 56px);
@include border-radius(2px 0 0 0);
}
.sidebar__overlay {
width: 100%;
height: 100%;
background-color: yellow;
@include opacity(.1);
position: absolute;
z-index: 5;
background-color: $yellow;
height: 100%;
pointer-events: none;
position: absolute;
width: 100%;
z-index: 5;
}
.input-group {
@@ -66,17 +66,17 @@
}
.sidebar--right__close {
margin: 11px 0 0 0;
width: 22px;
height: 22px;
opacity: .5;
font-size: 22px;
line-height: 0;
background: none;
float: right;
outline: none;
border: none;
@include single-transition(all, .2s, ease-in);
background: none;
border: none;
float: right;
font-size: 22px;
height: 22px;
line-height: 0;
margin: 11px 0 0;
opacity: .5;
outline: none;
width: 22px;
&:hover,
&:active {
@@ -90,14 +90,14 @@
}
.sidebar--right__header {
font-size: 1em;
text-transform: uppercase;
color: inherit;
height: 44px;
padding: 0 1em;
line-height: 44px;
@include flex(0 0 44px);
border-bottom: $border-gray;
color: inherit;
font-size: 1em;
height: 44px;
line-height: 44px;
padding: 0 1em;
text-transform: uppercase;
}
.sidebar--right__subheader {

Просмотреть файл

@@ -1,11 +1,11 @@
@charset 'UTF-8';
.webhooks__container {
background: rgba(black, .1);
border: 1px solid;
@include border-radius(3px);
padding: 0 13px 15px;
@include alpha-property(background, $black, .1);
border: 1px solid;
margin-top: 10px;
padding: 0 13px 15px;
}
.webhook__item {
@@ -19,16 +19,16 @@
}
.webhook__remove {
position: absolute;
right: -7px;
top: 8px;
width: 30px;
height: 30px;
color: #e05f5d;
font-size: 22px;
font-weight: bold;
height: 30px;
position: absolute;
right: -7px;
text-align: center;
text-decoration: none;
color: #e05f5d;
top: 8px;
width: 30px;
}
.webhook__url {

Просмотреть файл

@@ -32,21 +32,23 @@
.tip-overlay {
&.tip-overlay--chat {
margin: -10px 0 0 -10px;
.arrow {
right: 15px;
left: auto;
right: 15px;
}
}
}
.inner-wrap {
&.move--left {
.file-overlay {
font-size: em(18px);
.overlay__circle {
width: 300px;
height: 300px;
margin: -150px 0 0 -150px;
width: 300px;
}
.overlay__files {
@@ -62,4 +64,4 @@
.modal-lg {
width: 700px;
}
}
}

Просмотреть файл

@@ -519,7 +519,7 @@
.search-bar__container {
padding: 0;
@include flex(0 0 44px);
background: $color--primary;
background: $primary-color;
color: #fff;
&.focused {
@@ -756,9 +756,11 @@
.app__content {
padding-top: 45px;
margin: 0;
.channel__wrap & {
padding-top: 45px;
}
#channel-header {
display: none;
}
@@ -775,11 +777,6 @@
.post-comments {
padding: 9px 21px 10px 10px !important;
}
.post-image__column .post-image .file-playback__controls.stop,
.image-wrapper > a .file-playback__controls.stop {
@include opacity(1);
}
}
@media screen and (max-width: 640px) {

Просмотреть файл

@@ -2,9 +2,9 @@
@media screen and (max-width: 960px) {
.sidebar--right {
z-index: 5;
@include translateX(100%);
@include single-transition(all, .5s, ease);
@include translateX(100%);
z-index: 5;
&.move--left {
@include translateX(0);
@@ -32,4 +32,4 @@
.second-bar {
display: none;
}
}
}

Просмотреть файл

@@ -2,9 +2,9 @@
.access-history__table {
display: table;
width: 100%;
padding-top: 15px;
line-height: 1.6;
padding-top: 15px;
width: 100%;
&:first-child {
padding: 0;
@@ -16,8 +16,8 @@
}
.access__date {
font-weight: 600;
font-size: 15px;
font-weight: 600;
width: 190px;
}

Просмотреть файл

@@ -1,36 +1,27 @@
@charset 'UTF-8';
@keyframes highlight {
from {
background: rgba(yellow, .5);
}
to {
background: none;
}
}
.animation--highlight {
&:before {
content: '';
animation: highlight 1.5s ease;
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.activity-log__table {
border-top: 1px solid $light-gray;
display: table;
width: 100%;
line-height: 1.8;
border-top: 1px solid #ddd;
padding: 15px 0;
width: 100%;
&:first-child {
padding-top: 0;
border: none;
padding-top: 0;
}
> div {
@@ -49,6 +40,7 @@
.report__platform {
font-size: 15px;
font-weight: 600;
.fa {
margin-right: 6px;
}

Просмотреть файл

@@ -15,26 +15,25 @@
}
h3 {
font-weight: 600;
border-bottom: 1px solid #ddd;
padding-bottom: .5em;
font-weight: 600;
margin: 1em 0;
padding-bottom: .5em;
}
.table {
background: #fff;
background: $white;
}
.form-control {
background-color: #fff;
background-color: $white;
border: 1px solid #ccc;
color: #555;
&:focus {
@include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6));
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
}
}
@@ -42,7 +41,7 @@
color: #333;
&.btn-primary {
background: #2389d7;
background: $primary-color;
&:hover,
&:focus,
@@ -53,7 +52,7 @@
}
.dropdown-menu {
background: #fff;
background: $white;
border: 1px solid rgba(0,0,0,.15);
color: inherit;
}
@@ -86,38 +85,38 @@
> h4 {
background: #333;
padding: 10px 10px;
margin: 1px 0 0;
padding: 10px;
.menu-icon--right {
top: 6px;
right: 12px;
top: 6px;
}
}
}
.menu-icon--right {
position: absolute;
right: 10px;
top: 3px;
font-size: 18px;
font-weight: 600;
width: 20px;
height: 20px;
line-height: 20px;
position: absolute;
right: 10px;
text-align: center;
top: 3px;
width: 20px;
.fa {
color: $white;
font-size: 13px;
right: -2px;
position: relative;
color: #fff;
right: -2px;
}
}
&.nav__sub-menu {
@include font-smoothing(initial);
background: #111;
-webkit-font-smoothing: auto;
&.padded {
padding: 5px 0;
@@ -125,30 +124,31 @@
li {
> a {
font-size: 13px;
padding: 5px 35px 5px 15px;
background: transparent;
color: #bbb;
font-size: 13px;
padding: 5px 35px 5px 15px;
&:hover {
color: lighten($color--primary, 10);
color: lighten($primary-color, 10);
}
&.active {
color: #fff;
color: $white;
font-weight: 600;
}
}
.nav-more {
font-size: 13px;
padding: 5px 15px;
background: transparent;
color: #bbb;
display: block;
cursor: pointer;
display: block;
font-size: 13px;
padding: 5px 15px;
&:hover {
color: lighten($color--primary, 10);
color: lighten($primary-color, 10);
}
}
}
@@ -166,13 +166,13 @@
}
.log__panel {
overflow: scroll;
width: 100%;
height: 800px;
border: 1px solid #ddd;
margin-top: 10px;
padding: 5px;
background-color: white;
border: 1px solid #ddd;
height: 800px;
margin-top: 10px;
overflow: scroll;
padding: 5px;
width: 100%;
}
.compliance__panel {
@@ -199,10 +199,10 @@
color: #333;
&.admin {
overflow: auto;
background-color: #f1f1f1;
padding: 0 20px 20px;
min-height: 600px;
overflow: auto;
padding: 0 20px 20px;
}
.wrapper--fixed {
@@ -213,9 +213,9 @@
margin-top: 40px;
.control-label {
text-align: left;
padding-right: 0;
font-weight: 600;
padding-right: 0;
text-align: left;
}
.form-group {
@@ -223,22 +223,25 @@
}
.file__upload {
position: relative;
margin: 0 10px 10px 0;
display: inline-block;
margin: 0 10px 10px 0;
position: relative;
input {
position: absolute;
@include opacity(0);
width: 100%;
height: 100%;
z-index: 5;
top: 0;
left: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 5;
}
}
.help-text {
color: #777;
margin: 10px 0 0 15px;
&.no-margin {
margin: 0;
}
@@ -248,9 +251,6 @@
padding-left: 23px;
}
margin: 10px 0 0 15px;
color: #777;
.help-link {
margin-right: 5px;
}
@@ -262,10 +262,10 @@
.alert {
display: inline-block;
padding: 5px 7px;
margin: 1em 0 0;
top: 1px;
padding: 5px 7px;
position: relative;
top: 1px;
.fa {
margin-right: 5px;
@@ -274,11 +274,11 @@
}
.banner {
background: #fff;
background: $white;
border: 1px solid #ddd;
padding: .7em 1.5em;
font-size: .95em;
margin: 2em 0;
padding: .7em 1.5em;
.banner__heading {
font-size: 1.5em;
@@ -295,19 +295,19 @@
.popover {
border-radius: 3px;
width: 100%;
font-size: .95em;
width: 100%;
}
.panel {
border: none;
background-color: transparent;
border: none;
}
.panel-default {
> .panel-heading {
padding: 10px 0;
background-color: transparent;
padding: 10px 0;
}
.panel-body {
@@ -324,9 +324,9 @@
line-height: 1.5;
a {
text-decoration: none;
display: block;
@include clearfix;
display: block;
text-decoration: none;
&.collapsed {
.fa-minus {
@@ -339,10 +339,10 @@
}
.fa {
font-size: 18px;
float: right;
margin-top: 8px;
color: #aaa;
float: right;
font-size: 18px;
margin-top: 8px;
}
.fa-plus {

Просмотреть файл

@@ -5,15 +5,15 @@
padding-bottom: 20px;
> div {
width: 1170px;
margin: 0 auto;
padding: 0 15px;
max-width: 100%;
padding: 0 15px;
width: 1170px;
}
h1.markdown__heading {
border-bottom: 1px solid #ddd;
padding-bottom: 1rem;
margin: 1em 0 1em;
padding-bottom: 1rem;
}
}

Просмотреть файл

@@ -8,23 +8,23 @@ body {
}
.error__container {
max-width: 800px;
margin: 0 auto;
color: #555;
display: table-cell;
vertical-align: top;
margin: 0 auto;
max-width: 800px;
padding: 5em 0;
text-align: left;
color: #555;
vertical-align: top;
}
.error__icon {
font-size: 4em;
color: #ccc;
font-size: 4em;
}
h2 {
font-weight: 600;
font-size: 1.5em;
font-weight: 600;
margin: .8em 0 .5em;
}

Просмотреть файл

@@ -4,32 +4,32 @@
.loading-screen {
display: table;
width: 100%;
height: 100%;
padding: 60px;
text-align: center;
width: 100%;
.loading__content {
display: table-cell;
vertical-align: middle;
font-size: 0;
vertical-align: middle;
h3 {
display: inline-block;
font-size: 16px;
font-weight: 400;
margin: 0 .2em 0;
display: inline-block;
margin: 0 .2em;
}
.round {
background-color: #444;
width: 4px;
height: 4px;
@include animation(move .75s infinite linear);
@include border-radius(10px);
background-color: #444444;
display: inline-block;
height: 4px;
margin: 0 2px;
opacity: .1;
@include border-radius(10px);
@include animation(move .75s infinite linear);
width: 4px;
}
@for $i from 1 through 3 {
@@ -42,6 +42,7 @@
from {
opacity: 1;
}
to {
opacity: .1;
}

Просмотреть файл

@@ -2,41 +2,47 @@
.user-settings {
min-height: 300px;
.table-responsive {
max-width: 560px;
max-height: 300px;
max-width: 560px;
}
}
.modal {
.settings-modal {
width: 800px;
.modal-back {
width: 50px;
height: 40px;
top: 12px;
font-size: 27px;
font-weight: normal;
height: 40px;
left: 0;
line-height: 32px;
position: absolute;
left: 0;
text-align: center;
top: 12px;
width: 50px;
.fa {
height: 100%;
left: 0;
line-height: inherit;
position: absolute;
width: 100%;
height: 100%;
left: 0;
}
}
.modal-body {
padding: 0;
margin: 0 auto;
min-height: calc(100% - 62px);
padding: 0;
}
li {
list-style: none;
}
label {
font-weight: 600;
}
@@ -44,87 +50,110 @@
.no-padding--left {
padding-left: 0;
}
.padding-top {
padding-top: 7px;
&.x2 {
padding-top: 14px;
}
&.x3 {
padding-top: 21px;
}
}
.padding-bottom {
padding-bottom: 7px;
&.x2 {
padding-bottom: 14px;
}
&.x3 {
padding-bottom: 21px;
}
.control-label {
font-weight: 600;
&.text-left {
text-align: left;
}
}
}
.profile-img {
width: 128px;
height: 128px;
width: 128px;
}
.settings-table {
max-width: 1000px;
margin: 0 auto;
display: table;
margin: 0 auto;
max-width: 1000px;
table-layout: fixed;
width: 100%;
> div {
display: table-cell;
vertical-align: top;
}
.nav {
position: fixed;
width: 179px;
&.position--top {
top: 57px;
}
}
.security-links {
margin-right: 20px;
.fa {
margin-right: 6px;
}
}
.settings-links {
width: 180px;
}
.settings-content {
padding: 0px 20px 30px;
padding: 0 20px 30px;
.modal-header {
display: none;
}
.section-min {
padding: 1em 0;
margin-bottom: 0;
cursor: pointer;
position: relative;
@include clearfix;
&:hover {
background: #f9f9f9;
}
&:hover .fa {
display: inline-block;
}
&:hover .section-edit {
text-decoration: underline;
}
}
.section-max {
background: rgba(black, .05);
padding: 1em 0 1.3em;
margin-bottom: 0;
@include clearfix;
@include alpha-property(background, $black, .05);
margin-bottom: 0;
padding: 1em 0 1.3em;
.section-title {
margin-bottom: 10px;
}
@@ -136,50 +165,54 @@
padding: 4px 5px;
width: 40px;
}
img {
border: 1px solid rgba(black, .15);
width: 29px;
}
}
.group--code {
select {
@include appearance(none);
appearance: none;
padding-right: 25px;
&::ms-expand {
display: none;
}
}
select::-ms-expand {
display: none;
}
&:before {
pointer-events: none;
position: absolute;
top: 11px;
right: 50px;
z-index: 5;
@include font-smoothing;
content: '\f0d7';
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
pointer-events: none;
position: absolute;
right: 50px;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
top: 11px;
z-index: 5;
}
}
.premade-themes {
margin-bottom: 10px;
.theme-label {
font-weight: 400;
margin-top: 5px;
}
img {
border: 3px solid transparent;
}
.active {
img {
border-color: $color--primary;
border-color: $primary-color;
}
}
}
@@ -197,12 +230,12 @@
}
.theme-elements__header {
margin: 10px 20px 0px 0;
border-bottom: 1px solid #ccc;
padding: 5px 0 10px;
cursor: pointer;
font-size: em(13.5px);
font-weight: 600;
cursor: pointer;
margin: 10px 20px 0 0;
padding: 5px 0 10px;
.fa-minus {
display: none;
@@ -212,39 +245,41 @@
.fa-minus {
display: inline-block;
}
.fa-plus {
display: none;
}
}
.header__icon {
float: right;
@include opacity(.5);
float: right;
}
}
.theme-elements__body {
padding-top: 5px;
display: none;
@include legacy-pie-clearfix;
background: rgba(255, 255, 255, .05);
padding: 20px 0 0 20px;
margin: 0 20px 0 0;
@include border-radius(0 0 3px 3px);
@include legacy-pie-clearfix;
@include alpha-property(background-color, $white, .05);
display: none;
margin: 0 20px 0 0;
padding: 20px 0 0 20px;
}
.custom-label {
white-space: nowrap;
font-weight: normal;
font-size: 12px;
width: 100%;
font-weight: normal;
margin-bottom: 0;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 0;
white-space: nowrap;
width: 100%;
}
.input-group-addon {
background: transparent;
}
.radio {
label {
font-weight: 600;
@@ -253,32 +288,33 @@
}
.section-title {
margin-bottom: 5px;
font-weight: 600;
margin-bottom: 5px;
padding-right: 50px;
}
.section-edit {
text-align: right;
margin-bottom: 5px;
text-align: right;
.fa {
margin-right: 5px;
font-size: 12px;
@include opacity(.5);
display: none;
font-size: 12px;
margin-right: 5px;
&.fa-chevron-down {
top: -1px;
margin-right: 0;
position: relative;
top: -1px;
}
}
}
.section-describe {
@include opacity(.7);
white-space: pre;
@include clearfix;
@include opacity(.7);
text-overflow: ellipsis;
white-space: pre;
}
.divider-dark {
@@ -290,8 +326,8 @@
}
.setting-list {
padding: 0;
list-style-type: none;
padding: 0;
}
.setting-list__hint {
@@ -305,68 +341,77 @@
.setting-list-item {
margin-top: 7px;
}
.has-error {
color: #a94442;
}
.file-status {
color: #555;
font-size: 13px;
margin-top: 8px;
color: #555;
}
.confirm-import {
padding: 4px 10px;
margin: 10px 0;
padding: 4px 10px;
}
}
}
}
.nav-pills {
> li {
margin: 0;
a {
padding: 8px 5px 8px 15px;
border-radius: 0;
color: #777;
padding: 8px 5px 8px 15px;
}
.glyphicon {
width: 25px;
top: 2px;
width: 25px;
}
&:hover {
a {
background-color: rgba(black, .1);
@include alpha-property(background-color, $black, .1);
}
}
&.active {
a {
color: #111;
background-color: #e1e1e1;
color: #111;
&:before {
background: $black;
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
left: 0;
width: 5px;
height: 100%;
background: #000;
}
}
a,
a:hover,
a:focus {
background-color: rgba(black, .1);
@include alpha-property(background-color, $black, .1);
border-radius: 0;
font-weight: 400;
position: relative;
white-space: nowrap;
overflow: hidden;
position: relative;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
h3 {
font-size: em(20px);
}
@@ -391,13 +436,15 @@
.member-div {
border-bottom: 1px solid lightgrey;
position: relative;
padding: 2px;
margin: 0;
padding: 2px;
position: relative;
width: 100%;
&:first-child {
border-top: 1px solid lightgrey;
}
.post-profile-img {
@include border-radius(50px);
margin-right: 8px;
@@ -407,14 +454,14 @@
.member-role,
.member-drop {
.fa {
margin-right: 5px;
@include opacity(.5);
font-size: 12px;
margin-right: 5px;
}
.member-menu {
top: -50%;
right: 110%;
top: -50%;
}
}
@@ -425,13 +472,13 @@
}
.member-menu {
right: 0px;
left: auto;
right: 0;
}
.member-list {
width: 100%;
overflow-x: visible;
width: 100%;
}
.member-page {

Просмотреть файл

@@ -1,19 +1,19 @@
@charset 'UTF-8';
.signup-header {
width: 100%;
background: $bg--gray;
line-height: 33px;
padding: 0 1em .2em;
background: $bg--gray;
width: 100%;
.fa {
margin-right: 5px;
}
}
.signup-team__container {
padding: 100px 0px 50px 0px;
max-width: 380px;
margin: 0 auto;
max-width: 380px;
padding: 100px 0 50px;
position: relative;
&.padding--less {
@@ -21,7 +21,7 @@
}
.form-control:focus {
@include box-shadow(inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6));
@include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6));
}
h1,
@@ -39,16 +39,16 @@
}
h2 {
font-weight: 600;
margin-bottom: .8em;
letter-spacing: -.5px;
font-size: em(30px);
font-weight: 600;
letter-spacing: -.5px;
margin-bottom: .8em;
}
h3 {
font-weight: 600;
margin: 0 0 1.3em 0;
font-size: 1.5em;
font-weight: 600;
margin: 0 0 1.3em;
}
h4 {
@@ -66,7 +66,7 @@
}
p {
color: #555;
color: #555555;
line-height: 1.5;
margin-bottom: 1em;
}
@@ -81,32 +81,32 @@
}
.form-control {
text-align: left;
display: table-cell;
text-align: left;
width: 100%;
}
.input-group-addon {
text-align: left;
width: 50%;
display: table-cell;
overflow: hidden;
text-align: left;
text-overflow: ellipsis;
width: 50%;
}
}
}
.inner__content {
padding: 0 1rem;
margin: 30px 0 20px;
padding: 0 1rem;
}
.block--gray {
@include border-radius(3px);
background: #f2f2f2;
display: inline-block;
padding: .85em 1.2em;
font-weight: 600;
@include border-radius(3px);
padding: .85em 1.2em;
}
form {
@@ -114,32 +114,32 @@
}
.signup-team-confirm__container {
padding: 100px 0px 100px 0px;
padding: 100px 0;
}
.signup-team-logo {
display: none;
margin: 0 0 2em;
width: 210px;
margin: 0 0 2em 0;
}
.signup-team-login {
padding-bottom: 10px;
font-weight: 600;
padding-bottom: 10px;
}
.signup-team__name {
margin: .5em 0 0;
font-size: 2.2em;
font-weight: 600;
margin: .5em 0 0;
padding-left: 1rem;
}
.signup-team__subdomain {
margin: .2em 0 1.2em;
font-size: 1.5em;
padding-left: 1rem;
font-weight: 300;
margin: .2em 0 1.2em;
padding-left: 1rem;
text-transform: uppercase;
}
@@ -148,21 +148,21 @@
}
.or__container {
background: #dddddd;
height: 1px;
background: #ddd;
text-align: left;
margin: 2em 0;
text-align: left;
span {
width: 40px;
top: -10px;
position: relative;
font-size: 1.14286em;
line-height: 20px;
font-weight: 600;
background: #fff;
background: #ffffff;
display: inline-block;
font-size: 1.14286em;
font-weight: 600;
line-height: 20px;
position: relative;
text-align: center;
top: -10px;
width: 40px;
}
}
@@ -177,9 +177,9 @@
.btn {
font-size: 1em;
padding: em(7px) em(15px);
font-weight: 600;
margin-right: 5px;
padding: em(7px) em(15px);
.fa {
font-size: 17px;
@@ -187,29 +187,29 @@
}
.icon {
width: 18px;
height: 18px;
margin-right: 8px;
@include background-size(100% 100%);
display: inline-block;
height: 18px;
margin-right: 8px;
width: 18px;
}
&.btn-custom-login {
@include border-radius(2px);
color: $white;
display: block;
min-width: 200px;
width: 200px;
padding: 0 1em;
margin: 1em 1rem;
height: 40px;
line-height: 34px;
color: #fff;
@include border-radius(2px);
margin: 1em 1rem;
min-width: 200px;
padding: 0 1em;
width: 200px;
&.gitlab {
background: #548;
background: #554488;
&:hover {
background: darken(#548, 10%);
background: darken(#554488, 10%);
}
span {
@@ -250,10 +250,10 @@
}
&.email {
background: #2389d7;
background: $primary-color;
&:hover {
background: darken(#2389d7, 10%);
background: $primary-color--hover;
}
span {
@@ -269,15 +269,15 @@
}
&.btn-default {
color: #444;
color: #444444;
}
.glyphicon {
&.glyphicon-ok,
&.glyphicon-refresh {
margin-right: .5em;
left: -2px;
font-size: .9em;
left: -2px;
margin-right: .5em;
}
&.glyphicon-chevron-right {
@@ -296,28 +296,29 @@
.has-error {
.control-label {
background: #f2f2f2;
padding: .7em 1em;
@include border-radius(3px);
margin: 1em 0 0;
background: #f2f2f2;
color: #999999;
font-size: 14px;
font-weight: normal;
color: #999;
margin: 1em 0 0;
padding: .7em 1em;
width: 100%;
&:before {
@extend .fa;
@extend %font-awesome;
color: #aaaaaa;
content: '\f071';
margin-right: 4px;
color: #aaa;
}
}
}
.reset-form {
@include border-radius(3px);
position: relative;
font-size: .95em;
position: relative;
p {
color: inherit;
}
@@ -363,12 +364,12 @@
.black,
&.black {
color: #000;
color: #000000;
}
}
.color--light {
color: #777;
color: #777777;
}
.margin--extra {
@@ -381,9 +382,10 @@
}
.signup-team-all {
margin: 0 0 20px;
border: 1px solid #ddd;
@include border-radius(2px);
border: 1px solid #dddddd;
margin: 0 0 20px;
.signup-team-dir {
background: #fafafa;
border-top: 1px solid #d5d5d5;
@@ -395,25 +397,25 @@
a {
color: inherit;
display: block;
padding: 0 15px;
line-height: 3.5em;
height: 3.5em;
font-size: 1.1em;
height: 3.5em;
line-height: 3.5em;
padding: 0 15px;
}
}
.signup-team-dir__name {
white-space: nowrap;
float: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 90%;
}
.signup-team-dir__arrow {
color: #999999;
float: right;
font-size: .9em;
color: #999;
line-height: 3.5em;
}
}

Просмотреть файл

@@ -2,45 +2,45 @@
.team_statistics {
.total-count {
@include border-radius(3px);
background: $white;
border: 1px solid $light-gray;
margin: 1em 0;
text-align: center;
background: #fff;
border: 1px solid #ddd;
width: 100%;
@include border-radius(3px);
.title {
border-bottom: 1px solid $light-gray;
font-size: 13px;
font-weight: 400;
padding: 7px 10px;
border-bottom: 1px solid #ddd;
text-align: left;
font-size: 13px;
.fa {
color: #555555;
float: right;
margin: 0px 0 0;
color: #555;
font-size: 16px;
margin: 0;
}
}
.content {
color: #555555;
font-size: 30px;
font-weight: 600;
color: #555;
padding: .3em 0 .35em;
overflow: auto;
padding: .3em 0 .35em;
}
}
.total-count--day {
width: 760px;
height: 275px;
border: 1px solid #ddd;
padding: 5px 10px 10px 10px;
margin: 10px 10px 10px 10px;
background: #fff;
background: $white;
border: 1px solid $light-gray;
clear: both;
height: 275px;
margin: 10px;
padding: 5px 10px 10px;
width: 760px;
> div {
font-size: 18px;
@@ -50,8 +50,8 @@
.recent-active-users {
table {
width: 100%;
table-layout: fixed;
width: 100%;
}
.content {
@@ -68,14 +68,15 @@
}
td {
font-weight: 400;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 13px;
border-left: 1px solid #ddd;
border-top: 1px solid #ddd;
padding: 5px 5px 6px;
@include clearfix;
border-left: 1px solid $light-gray;
border-top: 1px solid $light-gray;
font-size: 13px;
font-weight: 400;
padding: 5px 5px 6px;
text-overflow: ellipsis;
white-space: nowrap;
&:first-child {
border-left: none;
}

Просмотреть файл

@@ -1,19 +1,21 @@
@charset 'UTF-8';
@-webkit-keyframes spin2 {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
from {
transform: scale(1) rotate(0deg);
}
to {
transform: scale(1) rotate(360deg);
}
}
@keyframes highlight {
from {
@include alpha-property(background, $yellow, .5);
}
to {
background: none;
}
}

Просмотреть файл

@@ -4,6 +4,20 @@
@return #{$pixels/$context}em
}
@function alpha-color($color, $amount) {
@return rgba($color, $amount)
}
%popover-box-shadow {
@include box-shadow(rgba(black, .175) 1px -3px 12px);
}
%font-awesome {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
transform: translate(0, 0);
}

Просмотреть файл

@@ -1,8 +1,29 @@
@charset 'UTF-8';
@mixin file-icon($path) {
background: #fff url($path);
@include background-size(60px auto);
background-color: $white;
background-image: url($path);
background-position: center;
background-repeat: no-repeat;
@include background-size(60px auto);
}
@mixin alpha-property($property, $color, $opacity) {
#{$property}: rgba($color, $opacity);
}
@mixin font-smoothing($value: antialiased) {
@if $value == antialiased {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@else {
-webkit-font-smoothing: subpixel-antialiased;
-moz-osx-font-smoothing: auto;
}
}
@mixin cursor($value) {
cursor: -webkit-$value;
cursor: zoom-$value;
}

Просмотреть файл

@@ -1,5 +1,5 @@
// Only for combining all the files in this folder
@import 'variables';
@import 'animations';
@import 'functions';
@import 'mixins';
@import 'animations';

Просмотреть файл

@@ -1,10 +1,16 @@
@charset 'UTF-8';
// Color Variables
$color--primary: rgb(35, 137, 215);
$color--primary--hover: darken($color--primary, 10%);
$primary-color: rgb(35, 137, 215);
$primary-color--hover: darken($primary-color, 10%);
$bg--gray: rgb(245, 245, 245);
$bg--white: rgb(255, 255, 255);
$white: rgb(255, 255, 255);
$black: rgb(0, 0, 0);
$red: rgb(229, 101, 101);
$yellow: rgb(255, 255, 0);
$light-gray: rgba(0, 0, 0, .06);
$gray: rgba(0, 0, 0, .3);
$dark-gray: rgba(0, 0, 0, .5);
// Page Variables
$border-gray: 1px solid #ddd;

Просмотреть файл

@@ -781,12 +781,12 @@ export function savePreferences(preferences, success, error) {
);
}
export function getSuggestedCommands(command, suggestionId, component) {
client.listCommands(
export function getSuggestedCommands(command, channelId, suggestionId, component) {
client.listCommands({command: command, channelId: channelId},
(data) => {
var matches = [];
data.forEach((cmd) => {
if (('/' + cmd.trigger).indexOf(command) === 0) {
if (('/' + cmd.trigger).indexOf(command) === 0 || cmd.external_management) {
let s = '/' + cmd.trigger;
let hint = '';
if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {

Просмотреть файл

@@ -1031,12 +1031,13 @@ export function regenCommandToken(data, success, error) {
});
}
export function listCommands(success, error) {
export function listCommands(data, success, error) {
$.ajax({
url: '/api/v1/commands/list',
dataType: 'json',
contentType: 'application/json',
type: 'GET',
type: 'POST',
data: JSON.stringify(data),
success,
error: function onError(xhr, status, err) {
var e = handleError('listCommands', xhr, status, err);

Просмотреть файл

@@ -145,7 +145,7 @@ export default {
PRESENTATION_TYPES: ['ppt', 'pptx'],
SPREADSHEET_TYPES: ['xlsx', 'csv'],
WORD_TYPES: ['doc', 'docx'],
CODE_TYPES: ['css', 'html', 'js', 'php', 'rb'],
CODE_TYPES: ['as', 'applescript', 'osascript', 'scpt', 'bash', 'sh', 'zsh', 'clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic', 'coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced', 'cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp', 'cs', 'csharp', 'css', 'd', 'di', 'dart', 'delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm', 'diff', 'django', 'jinja', 'dockerfile', 'docker', 'erl', 'f90', 'f95', 'fsharp', 'fs', 'gcode', 'nc', 'go', 'groovy', 'handlebars', 'hbs', 'html.hbs', 'html.handlebars', 'hs', 'hx', 'java', 'jsp', 'js', 'jsx', 'json', 'jl', 'kt', 'ktm', 'kts', 'less', 'lisp', 'lua', 'mk', 'mak', 'md', 'mkdown', 'mkd', 'matlab', 'm', 'mm', 'objc', 'obj-c', 'ml', 'perl', 'pl', 'php', 'php3', 'php4', 'php5', 'php6', 'ps', 'ps1', 'pp', 'py', 'gyp', 'r', 'ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb', 'rs', 'scala', 'scm', 'sld', 'scss', 'st', 'sql', 'swift', 'tex', 'vbnet', 'vb', 'bas', 'vbs', 'v', 'veo', 'xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist', 'yaml'],
PDF_TYPES: ['pdf'],
PATCH_TYPES: ['patch'],
ICON_FROM_TYPE: {
@@ -515,30 +515,64 @@ export default {
SPACE: 32,
TAB: 9
},
CODE_PREVIEW_MAX_FILE_SIZE: 500000, // 500 KB
HighlightedLanguages: {
diff: 'Diff',
apache: 'Apache',
makefile: 'Makefile',
http: 'HTTP',
json: 'JSON',
markdown: 'Markdown',
javascript: 'JavaScript',
css: 'CSS',
nginx: 'nginx',
objectivec: 'Objective-C',
python: 'Python',
xml: 'XML',
perl: 'Perl',
bash: 'Bash',
php: 'PHP',
coffeescript: 'CoffeeScript',
cs: 'C#',
cpp: 'C++',
sql: 'SQL',
go: 'Go',
ruby: 'Ruby',
java: 'Java',
ini: 'ini'
actionscript: {name: 'ActionScript', extensions: ['as']},
applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']},
bash: {name: 'Bash', extensions: ['bash', 'sh', 'zsh']},
clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']},
coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced']},
cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp']},
cs: {name: 'C#', extensions: ['cs', 'csharp']},
css: {name: 'CSS', extensions: ['css']},
d: {name: 'D', extensions: ['d', 'di']},
dart: {name: 'Dart', extensions: ['dart']},
delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']},
diff: {name: 'Diff', extensions: ['diff', 'patch']},
django: {name: 'Django', extensions: ['django', 'jinja']},
dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker']},
erlang: {name: 'Erlang', extensions: ['erl']},
fortran: {name: 'Fortran', extensions: ['f90', 'f95']},
fsharp: {name: 'F#', extensions: ['fsharp', 'fs']},
gcode: {name: 'G-Code', extensions: ['gcode', 'nc']},
go: {name: 'Go', extensions: ['go']},
groovy: {name: 'Groovy', extensions: ['groovy']},
handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars']},
haskell: {name: 'Haskell', extensions: ['hs']},
haxe: {name: 'Haxe', extensions: ['hx']},
java: {name: 'Java', extensions: ['java', 'jsp']},
javascript: {name: 'JavaScript', extensions: ['js', 'jsx']},
json: {name: 'JSON', extensions: ['json']},
julia: {name: 'Julia', extensions: ['jl']},
kotlin: {name: 'Kotlin', extensions: ['kt', 'ktm', 'kts']},
less: {name: 'Less', extensions: ['less']},
lisp: {name: 'Lisp', extensions: ['lisp']},
lua: {name: 'Lua', extensions: ['lua']},
makefile: {name: 'Makefile', extensions: ['mk', 'mak']},
markdown: {name: 'Markdown', extensions: ['md', 'mkdown', 'mkd']},
matlab: {name: 'Matlab', extensions: ['matlab', 'm']},
objectivec: {name: 'Objective C', extensions: ['mm', 'objc', 'obj-c']},
ocaml: {name: 'OCaml', extensions: ['ml']},
perl: {name: 'Perl', extensions: ['perl', 'pl']},
php: {name: 'PHP', extensions: ['php', 'php3', 'php4', 'php5', 'php6']},
powershell: {name: 'PowerShell', extensions: ['ps', 'ps1']},
puppet: {name: 'Puppet', extensions: ['pp']},
python: {name: 'Python', extensions: ['py', 'gyp']},
r: {name: 'R', extensions: ['r']},
ruby: {name: 'Ruby', extensions: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb']},
rust: {name: 'Rust', extensions: ['rs']},
scala: {name: 'Scala', extensions: ['scala']},
scheme: {name: 'Scheme', extensions: ['scm', 'sld']},
scss: {name: 'SCSS', extensions: ['scss']},
smalltalk: {name: 'Smalltalk', extensions: ['st']},
sql: {name: 'SQL', extensions: ['sql']},
swift: {name: 'Swift', extensions: ['swift']},
tex: {name: 'TeX', extensions: ['tex']},
vbnet: {name: 'VB.Net', extensions: ['vbnet', 'vb', 'bas']},
vbscript: {name: 'VBScript', extensions: ['vbs']},
verilog: {name: 'Verilog', extensions: ['v', 'veo']},
xml: {name: 'HTML, XML', extensions: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist']},
yaml: {name: 'YAML', extensions: ['yaml']}
},
PostsViewJumpTypes: {
BOTTOM: 1,
@@ -561,6 +595,10 @@ export default {
EMBED_TOGGLE: {
label: 'embed_toggle',
description: 'Show toggle for all embed previews'
},
SLASHCMD_AUTOCMP: {
label: 'slashCmd_autocmp',
description: 'Enable external application to offer slash command autocomplete'
}
},
OVERLAY_TIME_DELAY: 400,

Просмотреть файл

@@ -1,65 +1,14 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import highlightJs from 'highlight.js/lib/highlight.js';
import highlightJsDiff from 'highlight.js/lib/languages/diff.js';
import highlightJsApache from 'highlight.js/lib/languages/apache.js';
import highlightJsMakefile from 'highlight.js/lib/languages/makefile.js';
import highlightJsHttp from 'highlight.js/lib/languages/http.js';
import highlightJsJson from 'highlight.js/lib/languages/json.js';
import highlightJsMarkdown from 'highlight.js/lib/languages/markdown.js';
import highlightJsJavascript from 'highlight.js/lib/languages/javascript.js';
import highlightJsCss from 'highlight.js/lib/languages/css.js';
import highlightJsNginx from 'highlight.js/lib/languages/nginx.js';
import highlightJsObjectivec from 'highlight.js/lib/languages/objectivec.js';
import highlightJsPython from 'highlight.js/lib/languages/python.js';
import highlightJsXml from 'highlight.js/lib/languages/xml.js';
import highlightJsPerl from 'highlight.js/lib/languages/perl.js';
import highlightJsBash from 'highlight.js/lib/languages/bash.js';
import highlightJsPhp from 'highlight.js/lib/languages/php.js';
import highlightJsCoffeescript from 'highlight.js/lib/languages/coffeescript.js';
import highlightJsCs from 'highlight.js/lib/languages/cs.js';
import highlightJsCpp from 'highlight.js/lib/languages/cpp.js';
import highlightJsSql from 'highlight.js/lib/languages/sql.js';
import highlightJsGo from 'highlight.js/lib/languages/go.js';
import highlightJsRuby from 'highlight.js/lib/languages/ruby.js';
import highlightJsJava from 'highlight.js/lib/languages/java.js';
import highlightJsIni from 'highlight.js/lib/languages/ini.js';
highlightJs.registerLanguage('diff', highlightJsDiff);
highlightJs.registerLanguage('apache', highlightJsApache);
highlightJs.registerLanguage('makefile', highlightJsMakefile);
highlightJs.registerLanguage('http', highlightJsHttp);
highlightJs.registerLanguage('json', highlightJsJson);
highlightJs.registerLanguage('markdown', highlightJsMarkdown);
highlightJs.registerLanguage('javascript', highlightJsJavascript);
highlightJs.registerLanguage('css', highlightJsCss);
highlightJs.registerLanguage('nginx', highlightJsNginx);
highlightJs.registerLanguage('objectivec', highlightJsObjectivec);
highlightJs.registerLanguage('python', highlightJsPython);
highlightJs.registerLanguage('xml', highlightJsXml);
highlightJs.registerLanguage('perl', highlightJsPerl);
highlightJs.registerLanguage('bash', highlightJsBash);
highlightJs.registerLanguage('php', highlightJsPhp);
highlightJs.registerLanguage('coffeescript', highlightJsCoffeescript);
highlightJs.registerLanguage('cs', highlightJsCs);
highlightJs.registerLanguage('cpp', highlightJsCpp);
highlightJs.registerLanguage('sql', highlightJsSql);
highlightJs.registerLanguage('go', highlightJsGo);
highlightJs.registerLanguage('ruby', highlightJsRuby);
highlightJs.registerLanguage('java', highlightJsJava);
highlightJs.registerLanguage('ini', highlightJsIni);
import * as TextFormatting from './text_formatting.jsx';
import * as Utils from './utils.jsx';
import * as syntaxHightlighting from './syntax_hightlighting.jsx';
import marked from 'marked';
import katex from 'katex';
import 'katex/dist/katex.min.css';
import Constants from 'utils/constants.jsx';
const HighlightedLanguages = Constants.HighlightedLanguages;
function markdownImageLoaded(image) {
image.style.height = 'auto';
}
@@ -110,31 +59,11 @@ class MattermostMarkdownRenderer extends marked.Renderer {
this.formattingOptions = formattingOptions;
}
code(code, language, escaped) {
code(code, language) {
let usedLanguage = language || '';
usedLanguage = usedLanguage.toLowerCase();
// treat html as xml to prevent injection attacks
if (usedLanguage === 'html') {
usedLanguage = 'xml';
}
if (HighlightedLanguages[usedLanguage]) {
const parsed = highlightJs.highlight(usedLanguage, code);
return (
'<div class="post-body--code">' +
'<span class="post-body--code__language">' +
HighlightedLanguages[usedLanguage] +
'</span>' +
'<pre>' +
'<code class="hljs">' +
parsed.value +
'</code>' +
'</pre>' +
'</div>'
);
} else if (usedLanguage === 'tex' || usedLanguage === 'latex') {
if (usedLanguage === 'tex' || usedLanguage === 'latex') {
try {
const html = katex.renderToString(code, {throwOnError: false, displayMode: true});
@@ -144,13 +73,12 @@ class MattermostMarkdownRenderer extends marked.Renderer {
}
}
return (
'<pre>' +
'<code class="hljs">' +
(escaped ? code : TextFormatting.sanitizeHtml(code)) + '\n' +
'</code>' +
'</pre>'
);
// treat html as xml to prevent injection attacks
if (usedLanguage === 'html') {
usedLanguage = 'xml';
}
return syntaxHightlighting.formatCode(usedLanguage, code);
}
codespan(text) {

197
webapp/utils/syntax_hightlighting.jsx Обычный файл
Просмотреть файл

@@ -0,0 +1,197 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import * as Utils from './utils.jsx';
import * as TextFormatting from './text_formatting.jsx';
import Constants from './constants.jsx';
import hlJS from 'highlight.js/lib/highlight.js';
import hljsActionscript from 'highlight.js/lib/languages/actionscript.js';
import hljsApplescript from 'highlight.js/lib/languages/applescript.js';
import hljsBash from 'highlight.js/lib/languages/bash.js';
import hljsClojure from 'highlight.js/lib/languages/clojure.js';
import hljsCoffeescript from 'highlight.js/lib/languages/coffeescript.js';
import hljsCpp from 'highlight.js/lib/languages/cpp.js';
import hljsCs from 'highlight.js/lib/languages/cs.js';
import hljsCss from 'highlight.js/lib/languages/css.js';
import hljsD from 'highlight.js/lib/languages/d.js';
import hljsDart from 'highlight.js/lib/languages/dart.js';
import hljsDelphi from 'highlight.js/lib/languages/delphi.js';
import hljsDiff from 'highlight.js/lib/languages/diff.js';
import hljsDjango from 'highlight.js/lib/languages/django.js';
import hljsDockerfile from 'highlight.js/lib/languages/dockerfile.js';
import hljsErlang from 'highlight.js/lib/languages/erlang.js';
import hljsFortran from 'highlight.js/lib/languages/fortran.js';
import hljsFsharp from 'highlight.js/lib/languages/fsharp.js';
import hljsGcode from 'highlight.js/lib/languages/gcode.js';
import hljsGo from 'highlight.js/lib/languages/go.js';
import hljsGroovy from 'highlight.js/lib/languages/groovy.js';
import hljsHandlebars from 'highlight.js/lib/languages/handlebars.js';
import hljsHaskell from 'highlight.js/lib/languages/haskell.js';
import hljsHaxe from 'highlight.js/lib/languages/haxe.js';
import hljsJava from 'highlight.js/lib/languages/java.js';
import hljsJavascript from 'highlight.js/lib/languages/javascript.js';
import hljsJson from 'highlight.js/lib/languages/json.js';
import hljsJulia from 'highlight.js/lib/languages/julia.js';
import hljsKotlin from 'highlight.js/lib/languages/kotlin.js';
import hljsLess from 'highlight.js/lib/languages/less.js';
import hljsLisp from 'highlight.js/lib/languages/lisp.js';
import hljsLua from 'highlight.js/lib/languages/lua.js';
import hljsMakefile from 'highlight.js/lib/languages/makefile.js';
import hljsMarkdown from 'highlight.js/lib/languages/markdown.js';
import hljsMatlab from 'highlight.js/lib/languages/matlab.js';
import hljsObjectivec from 'highlight.js/lib/languages/objectivec.js';
import hljsOcaml from 'highlight.js/lib/languages/ocaml.js';
import hljsPerl from 'highlight.js/lib/languages/perl.js';
import hljsPhp from 'highlight.js/lib/languages/php.js';
import hljsPowershell from 'highlight.js/lib/languages/powershell.js';
import hljsPuppet from 'highlight.js/lib/languages/puppet.js';
import hljsPython from 'highlight.js/lib/languages/python.js';
import hljsR from 'highlight.js/lib/languages/r.js';
import hljsRuby from 'highlight.js/lib/languages/ruby.js';
import hljsRust from 'highlight.js/lib/languages/rust.js';
import hljsScala from 'highlight.js/lib/languages/scala.js';
import hljsScheme from 'highlight.js/lib/languages/scheme.js';
import hljsScss from 'highlight.js/lib/languages/scss.js';
import hljsSmalltalk from 'highlight.js/lib/languages/smalltalk.js';
import hljsSql from 'highlight.js/lib/languages/sql.js';
import hljsSwift from 'highlight.js/lib/languages/swift.js';
import hljsTex from 'highlight.js/lib/languages/tex.js';
import hljsVbnet from 'highlight.js/lib/languages/vbnet.js';
import hljsVbscript from 'highlight.js/lib/languages/vbscript.js';
import hljsVerilog from 'highlight.js/lib/languages/verilog.js';
import hljsXml from 'highlight.js/lib/languages/xml.js';
import hljsYaml from 'highlight.js/lib/languages/yaml.js';
hlJS.registerLanguage('actionscript', hljsActionscript);
hlJS.registerLanguage('applescript', hljsApplescript);
hlJS.registerLanguage('bash', hljsBash);
hlJS.registerLanguage('clojure', hljsClojure);
hlJS.registerLanguage('coffeescript', hljsCoffeescript);
hlJS.registerLanguage('cpp', hljsCpp);
hlJS.registerLanguage('cs', hljsCs);
hlJS.registerLanguage('css', hljsCss);
hlJS.registerLanguage('d', hljsD);
hlJS.registerLanguage('dart', hljsDart);
hlJS.registerLanguage('delphi', hljsDelphi);
hlJS.registerLanguage('diff', hljsDiff);
hlJS.registerLanguage('django', hljsDjango);
hlJS.registerLanguage('dockerfile', hljsDockerfile);
hlJS.registerLanguage('erlang', hljsErlang);
hlJS.registerLanguage('fortran', hljsFortran);
hlJS.registerLanguage('fsharp', hljsFsharp);
hlJS.registerLanguage('gcode', hljsGcode);
hlJS.registerLanguage('go', hljsGo);
hlJS.registerLanguage('groovy', hljsGroovy);
hlJS.registerLanguage('handlebars', hljsHandlebars);
hlJS.registerLanguage('haskell', hljsHaskell);
hlJS.registerLanguage('haxe', hljsHaxe);
hlJS.registerLanguage('java', hljsJava);
hlJS.registerLanguage('javascript', hljsJavascript);
hlJS.registerLanguage('json', hljsJson);
hlJS.registerLanguage('julia', hljsJulia);
hlJS.registerLanguage('kotlin', hljsKotlin);
hlJS.registerLanguage('less', hljsLess);
hlJS.registerLanguage('lisp', hljsLisp);
hlJS.registerLanguage('lua', hljsLua);
hlJS.registerLanguage('makefile', hljsMakefile);
hlJS.registerLanguage('markdown', hljsMarkdown);
hlJS.registerLanguage('matlab', hljsMatlab);
hlJS.registerLanguage('objectivec', hljsObjectivec);
hlJS.registerLanguage('ocaml', hljsOcaml);
hlJS.registerLanguage('perl', hljsPerl);
hlJS.registerLanguage('php', hljsPhp);
hlJS.registerLanguage('powershell', hljsPowershell);
hlJS.registerLanguage('puppet', hljsPuppet);
hlJS.registerLanguage('python', hljsPython);
hlJS.registerLanguage('r', hljsR);
hlJS.registerLanguage('ruby', hljsRuby);
hlJS.registerLanguage('rust', hljsRust);
hlJS.registerLanguage('scala', hljsScala);
hlJS.registerLanguage('scheme', hljsScheme);
hlJS.registerLanguage('scss', hljsScss);
hlJS.registerLanguage('smalltalk', hljsSmalltalk);
hlJS.registerLanguage('sql', hljsSql);
hlJS.registerLanguage('swift', hljsSwift);
hlJS.registerLanguage('tex', hljsTex);
hlJS.registerLanguage('vbnet', hljsVbnet);
hlJS.registerLanguage('vbscript', hljsVbscript);
hlJS.registerLanguage('verilog', hljsVerilog);
hlJS.registerLanguage('xml', hljsXml);
hlJS.registerLanguage('yaml', hljsYaml);
const HighlightedLanguages = Constants.HighlightedLanguages;
export function formatCode(lang, data, filename) {
var language = lang || '';
var parsed;
var header = '';
language = language.toLowerCase();
if (HighlightedLanguages[language]) {
var name = HighlightedLanguages[language].name;
if (filename) {
const fname = decodeURIComponent(Utils.getFileName(filename));
name = fname + ' - ' + name;
}
header = '<span class="post-body--code__language">' + name + '</span>';
try {
parsed = hlJS.highlight(language, data).value;
} catch (e) {
parsed = TextFormatting.sanitizeHtml(data);
}
} else {
parsed = TextFormatting.sanitizeHtml(data);
}
const lines = data.match(/\r\n|\r|\n|$/g).length;
var strlines = '';
for (var i = 1; i <= lines; i++) {
if (strlines) {
strlines += '\n' + i;
} else {
strlines += i;
}
}
return (
'<div class="post-body--code">' +
header +
'<pre>' +
'<code class="hljs">' +
'<table>' +
'<tbody>' +
'<tr>' +
'<td class="post-body--code__lineno">' + strlines + '</td>' +
'<td>' +
parsed +
'</td>' +
'</tr>' +
'</tbody>' +
'</table>' +
'</code>' +
'</pre>' +
'</div>'
);
}
export function getLang(filename) {
const fileInfo = Utils.splitFileLocation(filename);
var ext = fileInfo.ext;
if (!ext) {
return null;
}
ext = ext.toLowerCase();
for (var key in HighlightedLanguages) {
if (HighlightedLanguages[key].extensions.find((x) => x === ext)) {
return key;
}
}
return null;
}

Просмотреть файл

@@ -213,6 +213,11 @@ function highlightCurrentMentions(text, tokens) {
}
for (const mention of UserStore.getCurrentMentionKeys()) {
// occasionally we get an empty mention which matches a bunch of empty strings
if (!mention) {
continue;
}
output = output.replace(new RegExp(`(^|\\W)(${escapeRegex(mention)})\\b`, 'gi'), replaceCurrentMentionWithToken);
}

Просмотреть файл

@@ -680,7 +680,7 @@ export function applyTheme(theme) {
}
if (theme.centerChannelBg) {
changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content', 'background:' + theme.centerChannelBg, 1);
changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content, .modal .modal-back', 'background:' + theme.centerChannelBg, 1);
changeCss('#post-list .post-list-holder-by-time', 'background:' + theme.centerChannelBg, 1);
changeCss('#post-create', 'background:' + theme.centerChannelBg, 1);
changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1);
@@ -763,7 +763,6 @@ export function applyTheme(theme) {
if (theme.buttonBg) {
changeCss('.btn.btn-primary, .tutorial__circles .circle.active', 'background:' + theme.buttonBg, 1);
changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background:' + changeColor(theme.buttonBg, -0.25), 1);
changeCss('.file-playback__controls', 'color:' + changeColor(theme.buttonBg, -0.25), 1);
}
if (theme.buttonColor) {

Просмотреть файл

@@ -17,20 +17,21 @@ module.exports = {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
loader: 'babel',
exclude: /(node_modules|non_npm_dependencies)/,
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['transform-runtime']
presets: ['react', 'es2015-webpack', 'stage-0'],
plugins: ['transform-runtime'],
cacheDirectory: true
}
},
{
test: /\.json$/,
loader: 'json-loader'
loader: 'json'
},
{
test: /(node_modules|non_npm_dependencies)\/.+\.(js|jsx)$/,
loader: 'imports-loader',
loader: 'imports',
query: {
$: 'jquery',
jQuery: 'jquery'
@@ -46,7 +47,7 @@ module.exports = {
},
{
test: /\.(png|eot|tiff|svg|woff2|woff|ttf|gif)$/,
loader: 'file-loader',
loader: 'file',
query: {
name: 'files/[hash].[ext]'
}
@@ -67,7 +68,22 @@ module.exports = {
htmlExtract,
new CopyWebpackPlugin([
{from: 'images/emoji', to: 'emoji'}
])
]),
new webpack.optimize.UglifyJsPlugin({
'screw-ie8': true,
mangle: {
toplevel: false
},
compress: {
warnings: false
},
comments: false
}),
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
})
],
resolve: {
alias: {