I have a bot which is on a web widget, i will have this bot integrated to a parent application, from which i am fetching user's employee code. I want to handle the use case in which if a user is already talking to my bot i.e already in a session , then user cannot open another window from any other system or browser and talk at the same time. I want to map user's employee code in a way that if the above scenario happens my bot informs the user that you are already in session.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Digital Assistant</title>
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
<style>
.example {
float: left;
margin-right: 20px;
width: 300px;
}
.example > h2 {
font-family: 'Segoe UI';
}
#BotChatGoesHere {
border: 1px solid #333;
right: 10px;
height: 100%;
position: absolute;
width: 100%;
bottom:10px;
}
.wc-header {
background-color: #107ad1;
box-shadow: 0 1px rgba(0, 0, 0, 0.2);
box-sizing: content-box;
color: #ffffff;
font-weight: 500;
height: 40px;
left: 0;
letter-spacing: 0.5px;
padding: 8px 8px 0 8px;
position: absolute;
right: 0;
top: 0;
z-index: 1;
background-image: url(https://example.com/ess/App_Themes/HomepageBlue/images/tab_bg.jpg);
}
.wc-header span{
text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em darkblue;
font-size: 24px;
padding: 0 15px;
}
.wc-time {
color: #999999;
margin-bottom: 10px; }
.wc-message-groups {
bottom: 50px;
left: 0;
transform: translateY(0);
outline: 0;
overflow-x: hidden;
overflow-y: scroll;
padding: 10px;
position: absolute;
right: 0;
top: 38px;
transition: transform 0.2s cubic-bezier(0, 0, 0.5, 1);
background:linear-gradient(64deg,#1c627d 0,#1c637e 11%,#1b677f 20%,#196c81 27.5%,#177283 33.7%,#157986 38.8%,#138089 43.3%,#10888c 47.3%,#0e918f 51.2%,#0c9892 55.3%,#09a095 59.9%,#07a798 65.2%,#06ad9a 71.6%,#04b19b 79.3%,#03b49d 88.7%,#03b59d 100%);
}
.wc-message-groups.no-header {
top: 0; }
.wc-videocall-image{
cursor: pointer;
float: right;
width: 30px;
height: 30px;
margin-right: 12px;
border-radius: 50%;
font-size: 18px;
text-align: center;
line-height: 32px;
background: #ff60a9;
}
.userimage {
float: right;
width: 35px;
height: 35px;
text-align: center;
margin-right: 8px;
padding: 0;
margin-top: 0;
}
.userimage img {
width: 100%;
border-radius: 50%;
}
.userimage img:hover{
transform: scale(1.5);
}
.wc-message-content {
border-radius: 5px 10px 5px;
text-transform: capitalize;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.2);
padding: 8px;
word-break: break-word; }
.wc-message-from{
color:#ddd !important; }
.wc-message-from-me {
float: right;
margin-right: 6px; }
.wc-message-from-me.wc-message-from {
text-align: right; }
.wc-message-from-me .wc-message-content {
background-color: #107ad1;background-image: linear-gradient(#8bc4f3, #107ad1);
color: #ffffff; }
.wc-message-from-me svg.wc-message-callout path {
fill: #107ad1; }
.wc-message-from-me svg.wc-message-callout path.point-left {
display: none; }
/* from bot */
.wc-message-from-bot {
float: left;
margin-left: 8px; }
.wc-message-from-bot .wc-message-content {
background-color: #dcdcdc; background-image: linear-gradient(#d0caca, #efefef);
color: #000000; }
.wc-message-from-bot svg.wc-message-callout path {
fill: #dcdcdc; }
.wc-message-from-bot svg.wc-message-callout path.point-right {
display: none; }
.wc-message-from-bot svg.wc-message-callout {
left: -6px; }
</style>
</head>
<body>
<div id="BotChatGoesHere"></div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<!-- If you do not want to use Cognitive Services library, comment out the following line -->
<script src="https://cdn.botframework.com/botframework-webchat/latest/CognitiveServices.js"></script>
<script>
const params = BotChat.queryParams(location.search);
const user = {
id: params['userid'] || '5B6RnDTSIA4',
name: params['username'] || 'You',
usernametext:"You"
};
const bot = {
id: params['botid'] || 'mts-bot',
name: params['botname'] || 'ABC'
};
window.botchatDebug = params['debug'] && params['debug'] === 'true';
const styleOptions = {
botAvatarImage: 'https://learn.microsoft.com/en-us/azure/bot-service/v4sdk/media/logo_bot.svg?view=azure-bot-service-4.0',
botAvatarInitials: 'BF',
userAvatarImage: 'https://github.com/compulim.png?size=64',
userAvatarInitials: 'WC'
};
BotChat.App({
bot: bot,
chatTitle:"NIIT Digital Assistant",
locale: params['locale'],
resize: 'detect',
sendTyping: true, // defaults to false. set to true to send 'typing' activities to bot (and other users) when user is typing
speechOptions: speechOptions,
user: user,
styleOptions,
directLine: {
domain: params['webchat.botframework.com'],
secret: params['s'],
token: params['t'],
webSocket: params['webSocket'] && params['webSocket'] === 'true' // defaults to true
}
}, document.getElementById('BotChatGoesHere'));
</script>
</body>
</html>
Unfortunately, there is not a built-in or easy way to do this. You're going to have to cobble together a few additional things to make this work and there isn't really a "standard" answer. However, here's a couple of ways I can think to do this:
Both
Both of my ideas have similar starting components:
Use the employee's code as their user id:
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({
token: 'YOUR_DIRECT_LINE_TOKEN'
}),
userID: <theEmployeeCode>
},
document.getElementById('webchat')
);
Send an Event on Each Page Load
Send an event that fires on each page load
In the bot, by userId, keep track of when each event was received. Something like:
{
<userId>: {
lastJoinEvent: <timeOfLastJoinEvent>
}
}
In the bot, when a join event is received, check if <userId>.lastJoinEvent exists and if it does, you'll want to allow unique sessions after a certain amount of time (say they talked to the bot on a different day), so you'll need some logic that says if <timeOfLastCurrentEvent> - <timeOfLastJoinEvent> > 1 hour (or something), don't send the "session already open" message.
Send Additional Data With Each Message
Generate a constant random id (GUID or random string of some kind) each time the page is loaded, and send that with the activity's ChannelData.
For each message the bot receives from that userId, store an object something like:
{
<userId>: {
lastRandomId: <generatedRandomId>
lastMessageTimestamp: <timeOfLastMessage>
}
}
On each message, update the lastRandomId and the lastMessageTimestamp
In your bot, on each message, check that for the userId, the received randomId matches the lastRandomId. If it does, you can ensure that they're in the same session, so no need to send the "session already open" message.
If they do not match, the sessions are unique. However, you'll want to allow unique sessions after a certain amount of time (say they talked to the bot on a different day), so you'll need some logic that says if <currentMessageTimestamp> - <lastMessageTimestamp> > 1 hour (or something), don't send the "session already open" message.
Now, the problem with this is that you need to make this check on every single message, which is an "expensive" check for something like this. If your bot doesn't have a lot of users and you don't scale it horizontally, you could just store this map in memory--otherwise, you'd need a more permanent storage solution. So, of the two, I'd recommend the first.
All that being said, I recommend against this because:
This can only work in clients that you can either 1) send events on load, or 2) send channelData with every message. So, this would work in Web Chat, but not Teams
This is not easy to implement
If you scale your bot horizontally, you can't store this in memory, which means you're making additional storage API calls fairly frequently. Not too bad for the first options, but rules out the second.
There may be other ways to do this, too, but this is all I can think of.
I`m using css styles with xamarin forms. I`ve got grid wirh buttons:
StackLayout {
background-color: #1e1e1e;
color: #ffffff;
}
Button{
background-color: #2d2d30;
font-family: Consolas;
font-size: 24;
margin: 0;
}
And xaml:
<Grid>
<Grid.ColumnDefinitions>
/*...*/
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
/*...*/
</Grid.RowDefinitions>
<Button/>
<Button/>
/*...*/
</Grid>
How to remove this gaps between buttons?
This is inline-block elements issue. As you can see:
button {
width: 50px;
height: 50px;
background: #000;
outline:none;
border:none;
margin:0;
}
<button></button>
<button></button>
<button></button>
We can use these two methods to remove gaps.
Adjacent write
button {
width: 50px;
height: 50px;
background: #000;
outline:none;
border:none;
}
<button></button><button></button><button></button>
Comment line
button {
width: 50px;
height: 50px;
background: #000;
outline:none;
border:none;
}
<button></button><!--
--><button></button><!--
--><button></button>
Grid {
column-gap: 0;
row-gap: 0;
}
In my code behind I have the following:
public void btnDoSomething_Click(object sender, EventArgs e)
{
if (sku.Peso == 0)
{
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "Validation",
"<script type='text/javascript'>alert('You can't do that!');</script>", false);
pnlSKU.Style.Remove("visibility");
pnlSKU.Style.Add("visibility", "visible");
}
else
//It does something...
pnlSKU.Style.Remove("visibility");
pnlSKU.Style.Add("visibility", "visible");
}
In my aspx I have the following inside the panel pnlSKU:
<asp:Panel ID="pnlSKU" runat="server" Style="visibility: hidden; overflow-x: auto overflow-y: scroll; border-right: black thin solid;
border-top: black thin solid; z-index: 200; left: 210px; border-left: black thin solid;
border-bottom: black thin solid; position: absolute; top: 28%; height: 500px;
background-color: white; width: 900px;">
The code in itself is very much longer but It doesn't matter at this point.
Everytime the condition is met the control panel dissapears completely even If I call the method add to the Style property and put "visible".
Any idea why is happening?
I want my footer of the page to slide up onto the screen when my cursor is at the bottom of the browser. I don't have a clue on where to being but here is my CSS code for the footer:
footer {
background-color: #333;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 75px;
clear: both;
float:none;
}
you can do this with some jquery by wrapping the footer in a container
$(".footer-container").hover(function(){
$(".footer").stop().animate({"bottom": "0"});
},function(){
$(".footer").stop().animate({"bottom": "-75px"});
});
JSFIDDLE
You can use CSS Transitions to change properties' values over a specified duration in order to achieve the slide-up effect.
Whether to slide-up/expand the footer:
footer {
position: fixed;
bottom: 0; left: 0; right: 0;
height: 75px;
transition: height .2s ease-in; /* Use transition for 'height' or all */
}
footer:hover {
height: 50%; /* Change the height of the footer as the half of the screen */
}
WORKING DEMO.
Or to slide-up/display the footer on hover:
footer {
position: fixed;
bottom: -75px; left: 0; right: 0;
border-top: 20px solid transparent;
height: 75px;
transition: all .2s ease-in;
}
footer:hover { bottom: 0; }
UPDATED DEMO.
i have two popup windows in my Home Page (Default.aspx) like below :
apsx Code :
<div id="OffDiv">
</div>
<div id="TimerContainer">
<asp:Image ID="imgWhiteCircle" runat="server" ImageUrl="~/Images/WhiteCircle.png" />
<asp:Label ID="lblCountDown" runat="server" Text="60" Font-Bold="True" Font-Size="50px"
ForeColor="Black"></asp:Label>
</div>
css :
div#OffDiv
{
display: none;
position: fixed;
top: 0px;
right: 0px;
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
z-index: 90000;
background-color: black;
filter: alpha(opacity=30); /* internet explorer */
-khtml-opacity: 0.3; /* khtml, old safari */
-moz-opacity: 0.3; /* mozilla, netscape */
opacity: 0.3; /* fx, safari, opera */
}
div#TimerContainer
{
display: none;
position: absolute;
width: 110px;
height: 110px;
top: 200px;
left: 50%;
margin-left: -55px;
padding: 0px;
z-index: 90001;
}
#imgWhiteCircle
{
width: 110px;
}
#lblCountDown
{
position: absolute;
width: 70px;
height: 65px;
text-align: center;
top: 50%;
left: 50%;
margin-left: -35px;
margin-top: -32.5px;
}
JavaScript Code :
<script language="javascript" type="text/javascript">
$(function () {
var x = screen.availWidth;
$('div#OffDiv').css({ 'width': x });
var y = screen.availHeight;
$('div#OffDiv').css({ 'height': y });
$('div#OffDiv').css({ 'display': 'block' });
$('div#TimerContainer').css({ 'display': 'block' });
window.open('http://www.MyPoPUp1.com', '_blank', 'channelmode=no,directories=yes,location=no,resizable=yes,titlebar=yes,menubar=no,toolbar=no,scrollbars=yes,status=yes', false);
window.open('http://www.MyPoPUp2.com', '_blank', 'channelmode=no,directories=yes,location=no,resizable=yes,titlebar=yes,menubar=no,toolbar=no,scrollbars=yes,status=yes', false);
window.focus();
var sec = $('#TimerContainer span').text()
var timer = setInterval(function () {
$('#TimerContainer span').text(--sec);
if (sec == 0) {
clearInterval(timer);
$('div#OffDiv').css({ 'display': 'none' });
$('div#TimerContainer').css({ 'display': 'none' });
}
}, 1000);
}); //End Of $(function ()
</script>
as you see there is a countdown timer in parent window (starts from 60 seconds)
during this timer i do not want to let my users to close popup windows.
how can i do that?
or how can i show a message in parent window when user closes one of popup windows?
mean what is the way to make a connection between closing of popup windows and their parent window?
thanks in advance
This way you can get feedback whether the opened popup is closed or not.
var popup = window.open('http://www.google.com');
var timer = setInterval(function () {
if (popup.closed) {
alert('popup closed!');
clearInterval(timer);
}
}, 500);
Regards