Skip to content

Commit

Permalink
add profile image to plugin posts (#7)
Browse files Browse the repository at this point in the history
* add profile image to plugin posts
* fix S4B icon in webapp according to brand guidelines
* changed the icon in the channel header to a more generic video icon
  • Loading branch information
kosgrz authored May 29, 2019
1 parent e0014f9 commit 7317374
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 16 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ HTTP ?= $(shell command -v http 2> /dev/null)
CURL ?= $(shell command -v curl 2> /dev/null)
MANIFEST_FILE ?= plugin.json

# You can include assets this directory into the bundle. This can be e.g. used to include profile pictures.
ASSETS_DIR ?= assets

# Verify environment, and define PLUGIN_ID, PLUGIN_VERSION, HAS_SERVER and HAS_WEBAPP as needed.
include build/setup.mk

Expand Down Expand Up @@ -90,6 +93,9 @@ bundle:
rm -rf dist/
mkdir -p dist/$(PLUGIN_ID)
cp $(MANIFEST_FILE) dist/$(PLUGIN_ID)/
ifneq ($(wildcard $(ASSETS_DIR)/.),)
cp -r $(ASSETS_DIR) dist/$(PLUGIN_ID)/
endif
ifneq ($(HAS_SERVER),)
mkdir -p dist/$(PLUGIN_ID)/server/dist;
cp -r server/dist/* dist/$(PLUGIN_ID)/server/dist/;
Expand Down
Binary file added assets/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 32 additions & 3 deletions server/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ package main
import (
"encoding/json"
"fmt"
"github.com/mattermost/mattermost-server/mlog"
"io"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"sync"
Expand All @@ -19,7 +24,7 @@ import (
const (
POST_MEETING_KEY = "post_meeting_"
POST_MEETING_TYPE = "custom_s4b"
POST_MEETING_OVERRIDE_USERNAME = "Skype for Business"
POST_MEETING_OVERRIDE_USERNAME = "Skype for Business Plugin"
NEW_APPLICATION_USER_AGENT = "mm_skype4b_plugin"
NEW_APPLICATION_CULTURE = "en-US"
WS_EVENT_AUTHENTICATED = "authenticated"
Expand Down Expand Up @@ -76,6 +81,8 @@ func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Req
p.completeAuthorizeInADD(w, r)
case "/api/v1/register_meeting_from_online_version":
p.handleRegisterMeetingFromOnlineVersion(w, r)
case "/api/v1/assets/profile.png":
p.handleProfileImage(w, r)
default:
http.NotFound(w, r)
}
Expand Down Expand Up @@ -277,6 +284,8 @@ func (p *Plugin) handleRegisterMeetingFromOnlineVersion(w http.ResponseWriter, r
return
}

serverConfiguration := p.API.GetConfig()

post := &model.Post{
UserId: user.Id,
ChannelId: req.ChannelId,
Expand All @@ -290,7 +299,7 @@ func (p *Plugin) handleRegisterMeetingFromOnlineVersion(w http.ResponseWriter, r
"override_username": POST_MEETING_OVERRIDE_USERNAME,
"meeting_status": "STARTED",
"from_webhook": "true",
"override_icon_url": "", //todo
"override_icon_url": path.Join(*serverConfiguration.ServiceSettings.SiteURL, "plugins", manifest.Id, "api", "v1", "assets", "profile.png"),
},
}

Expand Down Expand Up @@ -368,6 +377,8 @@ func (p *Plugin) handleCreateMeetingInServerVersion(w http.ResponseWriter, r *ht
return
}

serverConfiguration := p.API.GetConfig()

post := &model.Post{
UserId: user.Id,
ChannelId: req.ChannelId,
Expand All @@ -381,7 +392,7 @@ func (p *Plugin) handleCreateMeetingInServerVersion(w http.ResponseWriter, r *ht
"meeting_topic": "Meeting created by " + user.Username,
"meeting_status": "STARTED",
"from_webhook": "true",
"override_icon_url": "", //todo
"override_icon_url": path.Join(*serverConfiguration.ServiceSettings.SiteURL, "plugins", manifest.Id, "api", "v1", "assets", "profile.png"),
},
}

Expand All @@ -406,6 +417,24 @@ func (p *Plugin) handleCreateMeetingInServerVersion(w http.ResponseWriter, r *ht
return
}

func (p *Plugin) handleProfileImage(w http.ResponseWriter, r *http.Request) {
bundlePath, err := p.API.GetBundlePath()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
img, err := os.Open(filepath.Join(bundlePath, "assets", "profile.png"))
if err != nil {
http.NotFound(w, r)
mlog.Error("Unable to read Skype 4 Business plugin profile image, err=" + err.Error())
return
}
defer img.Close()

w.Header().Set("Content-Type", "image/png")
io.Copy(w, img)
}

func (p *Plugin) fetchOnlineMeetingsUrl() (*ApplicationState, *APIError) {
config := p.getConfiguration()
discoveryUrl := "https://lyncdiscover." + config.Domain
Expand Down
13 changes: 13 additions & 0 deletions server/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ func TestPlugin(t *testing.T) {
Email: "theuseremail",
}, (*model.AppError)(nil))

siteUrl := "https://domain.test"
api.On("GetConfig").Return(&model.Config{
ServiceSettings: model.ServiceSettings{
SiteURL: &siteUrl,
},
})

api.On("GetChannelMember", "thechannelid", "theuserid").Return(&model.ChannelMember{}, (*model.AppError)(nil))
api.On("CreatePost", mock.AnythingOfType("*model.Post")).Return(&model.Post{}, (*model.AppError)(nil))
api.On("KVSet", fmt.Sprintf("%v%v", POST_MEETING_KEY, "L30IC51J"), mock.AnythingOfType("[]uint8")).Return((*model.AppError)(nil))
Expand Down Expand Up @@ -188,6 +195,12 @@ func TestPlugin(t *testing.T) {
clientMock.On("createNewMeeting", mock.Anything, mock.Anything, mock.Anything).Return(&NewMeetingResponse{
MeetingId: expectedMeetingId,
}, nil)
siteUrl := "https://domain.test"
api.On("GetConfig").Return(&model.Config{
ServiceSettings: model.ServiceSettings{
SiteURL: &siteUrl,
},
})

p := Plugin{client: clientMock}
p.setConfiguration(&configuration{
Expand Down
4 changes: 2 additions & 2 deletions webapp/src/components/icon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default class Icon extends React.PureComponent {
<span
style={style.iconStyle}
aria-hidden='true'
dangerouslySetInnerHTML={{__html: Svgs.SKYPE}}
dangerouslySetInnerHTML={{__html: Svgs.VIDEO_CAMERA}}
/>
);
}
Expand All @@ -25,7 +25,7 @@ const getStyle = makeStyleFromTheme(() => {
return {
iconStyle: {
position: 'relative',
top: '4px',
top: '-1px',
},
};
});
6 changes: 0 additions & 6 deletions webapp/src/components/post_type_s4b/post_type_s4b.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import PropTypes from 'prop-types';

import {makeStyleFromTheme} from 'mattermost-redux/utils/theme_utils';

import {Svgs} from '../../constants';

export default class PostTypeS4b extends React.PureComponent {
static propTypes = {

Expand Down Expand Up @@ -40,10 +38,6 @@ export default class PostTypeS4b extends React.PureComponent {
target='_blank'
href={props.meeting_link}
>
<i
style={style.buttonIcon}
dangerouslySetInnerHTML={{__html: Svgs.SKYPE_2}}
/>
{'JOIN MEETING'}
</a>
);
Expand Down
6 changes: 1 addition & 5 deletions webapp/src/constants/svgs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7317374

Please sign in to comment.