Skip to content

Commit bc11244

Browse files
authored
Merge pull request #44 from dotkernel/issue-38
Issue 38
2 parents 90d59dd + 5c28629 commit bc11244

170 files changed

Lines changed: 864 additions & 4974 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

public/css/app.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/js/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App/assets/js/components/_main.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,58 @@ function toggleTheme() {
1010
localStorage.setItem('theme', next);
1111
}
1212
window.toggleTheme = toggleTheme;
13+
14+
function closeAllMdActionsMenus(except) {
15+
document.querySelectorAll('.md-actions.open').forEach(function (wrapper) {
16+
if (wrapper !== except) {
17+
wrapper.classList.remove('open');
18+
wrapper.querySelector('.md-actions-toggle').setAttribute('aria-expanded', 'false');
19+
}
20+
});
21+
}
22+
23+
function toggleMdActionsMenu(button) {
24+
var wrapper = button.closest('.md-actions');
25+
var isOpen = wrapper.classList.contains('open');
26+
closeAllMdActionsMenus(wrapper);
27+
wrapper.classList.toggle('open', !isOpen);
28+
button.setAttribute('aria-expanded', String(!isOpen));
29+
}
30+
window.toggleMdActionsMenu = toggleMdActionsMenu;
31+
32+
document.addEventListener('click', function (event) {
33+
if (!event.target.closest('.md-actions')) {
34+
closeAllMdActionsMenus();
35+
}
36+
});
37+
38+
document.addEventListener('keydown', function (event) {
39+
if (event.key === 'Escape') {
40+
closeAllMdActionsMenus();
41+
}
42+
});
43+
44+
document.addEventListener('click', function (event) {
45+
var item = event.target.closest('[data-copy-url]');
46+
if (!item) {
47+
return;
48+
}
49+
event.preventDefault();
50+
51+
var url = item.getAttribute('data-copy-url');
52+
var label = item.querySelector('.label');
53+
var originalText = label.textContent;
54+
55+
fetch(url)
56+
.then(function (response) { return response.text(); })
57+
.then(function (markdown) { return navigator.clipboard.writeText(markdown); })
58+
.then(function () {
59+
label.textContent = 'Copied!';
60+
setTimeout(function () { label.textContent = originalText; }, 1500);
61+
})
62+
.catch(function () {
63+
navigator.clipboard.writeText(url);
64+
});
65+
66+
closeAllMdActionsMenus();
67+
});

src/App/assets/scss/components/_blog.scss

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,4 +502,129 @@ $bp-tablet: 900px;
502502
color: var(--text-dim);
503503
flex-shrink: 0;
504504
}
505-
}
505+
}
506+
507+
// ---------- Copy page / view as markdown / open in Claude dropdown ----------
508+
.md-actions {
509+
position: relative;
510+
display: inline-flex;
511+
}
512+
513+
.md-actions-toggle {
514+
display: inline-flex;
515+
align-items: stretch;
516+
padding: 0;
517+
border-radius: 8px;
518+
background: var(--surface);
519+
border: 1px solid var(--border);
520+
color: var(--text-muted);
521+
font-family: var(--sans);
522+
font-size: 13px;
523+
cursor: pointer;
524+
overflow: hidden;
525+
transition: box-shadow .15s ease, border-color .15s ease, color .15s ease;
526+
527+
svg {
528+
width: 14px;
529+
height: 14px;
530+
flex-shrink: 0;
531+
}
532+
533+
.chev {
534+
width: 12px;
535+
height: 12px;
536+
transition: transform .15s ease;
537+
}
538+
539+
&:hover {
540+
border-color: var(--text-dim);
541+
color: var(--text);
542+
box-shadow: 0 4px 12px rgba(0, 0, 0, .12);
543+
}
544+
}
545+
546+
.md-actions-toggle-label {
547+
display: inline-flex;
548+
align-items: center;
549+
gap: 8px;
550+
padding: 6px 12px;
551+
}
552+
553+
.md-actions-toggle-chev {
554+
display: inline-flex;
555+
align-items: center;
556+
padding: 6px 10px;
557+
border-left: 1px solid var(--border);
558+
}
559+
560+
.md-actions.open .md-actions-toggle {
561+
border-color: var(--text-dim);
562+
color: var(--text);
563+
box-shadow: 0 4px 12px rgba(0, 0, 0, .12);
564+
}
565+
566+
.md-actions.open .md-actions-toggle .chev {
567+
transform: rotate(180deg);
568+
}
569+
570+
.md-actions-menu {
571+
position: absolute;
572+
top: calc(100% + 8px);
573+
right: 0;
574+
min-width: 240px;
575+
background: var(--surface);
576+
border: 1px solid var(--border);
577+
border-radius: var(--radius);
578+
box-shadow: 0 12px 32px rgba(0, 0, 0, .18);
579+
padding: 6px;
580+
display: none;
581+
flex-direction: column;
582+
gap: 2px;
583+
z-index: 20;
584+
}
585+
586+
.md-actions.open .md-actions-menu {
587+
display: flex;
588+
}
589+
590+
.md-actions-item {
591+
display: flex;
592+
align-items: center;
593+
gap: 10px;
594+
padding: 8px 10px;
595+
border-radius: 8px;
596+
border: none;
597+
background: transparent;
598+
color: var(--text);
599+
font-family: var(--sans);
600+
font-size: 13px;
601+
text-align: left;
602+
text-decoration: none;
603+
cursor: pointer;
604+
605+
svg {
606+
width: 16px;
607+
height: 16px;
608+
color: var(--text-dim);
609+
flex-shrink: 0;
610+
}
611+
612+
&:hover {
613+
background: var(--surface-2);
614+
color: var(--amber);
615+
616+
svg {
617+
color: var(--amber);
618+
}
619+
}
620+
}
621+
622+
.md-actions-bar {
623+
display: flex;
624+
justify-content: flex-end;
625+
margin-bottom: 12px;
626+
627+
& + h2 {
628+
margin-top: 0;
629+
}
630+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{% extends '@layout/default.html.twig' %}
2+
3+
{% block json_ld %} {{ include('@jsonld/' ~ article.category.slug ~ '/' ~ article.slug ~ '.jsonld.twig') }} {% endblock %}
4+
5+
{% block title %}{{ article.title }}{% endblock %}
6+
7+
{% block page_title %}
8+
{{ include('@partial/title-section.html.twig', {
9+
back_href: url('page::blog'),
10+
back_label: 'Back to Blog',
11+
badge: article.category.name,
12+
article: article,
13+
}) }}
14+
{% endblock %}
15+
16+
{% block content %}
17+
<div class="wrap post-body-wrap">
18+
<div class="post-layout">
19+
20+
{{ include('@partial/left-menu.html.twig') }}
21+
22+
<article class="article">
23+
<div class="entry">
24+
{{ include('@partial/obsolete-warning.html.twig', {article: article}) }}
25+
{{ include('@partial/markdown-actions.html.twig', {article: article}) }}
26+
{% block body %}{% endblock %}
27+
</div>
28+
29+
{{ include('@partial/post-nav.html.twig') }}
30+
</article>
31+
32+
</div>
33+
</div>
34+
{% endblock %}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{% set markdown_url = url('app::markdown-article', {categorySlug: article.category.slug, slug: article.slug}) %}
2+
{% set claude_prompt = 'Read from ' ~ markdown_url ~ ' so I can ask questions about it.' %}
3+
<div class="md-actions-bar">
4+
<div class="md-actions">
5+
<button type="button" class="md-actions-toggle" aria-haspopup="true" aria-expanded="false" onclick="toggleMdActionsMenu(this)">
6+
<span class="md-actions-toggle-label">
7+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h9l7 7v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="M13 4v6h6"/></svg>
8+
<span>Copy Page</span>
9+
</span>
10+
<span class="md-actions-toggle-chev">
11+
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
12+
</span>
13+
</button>
14+
<div class="md-actions-menu" role="menu">
15+
<button type="button" class="md-actions-item" role="menuitem" data-copy-url="{{ markdown_url }}">
16+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>
17+
<span class="label">Copy Page (as Markdown)</span>
18+
</button>
19+
<a href="{{ markdown_url }}" target="_blank" rel="noopener noreferrer" class="md-actions-item" role="menuitem">
20+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h9l7 7v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z"/><path d="M13 4v6h6"/><path d="M8 15h8M8 11h4"/></svg>
21+
<span class="label">View as Markdown</span>
22+
</a>
23+
<a href="https://claude.ai/new?q={{ claude_prompt|url_encode }}" target="_blank" rel="noopener noreferrer" class="md-actions-item" role="menuitem">
24+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3l2.5 5.5L20 11l-5.5 2.5L12 19l-2.5-5.5L4 11l5.5-2.5z"/></svg>
25+
<span class="label">Open in Claude</span>
26+
</a>
27+
</div>
28+
</div>
29+
</div>

src/App/templates/partial/title-section.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
{% endif %}
3535
</div>
3636
{% endif %}
37-
{% if author_github %}
37+
{% if author_github and show_github is defined and show_github %}
3838
<div class="post-meta-v2 mt-3">
3939
<span class="meta-item">
4040
Also on

src/Blog/templates/page/author-resource.html.twig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
back_label: 'Back to Blog',
1010
badge: 'Author',
1111
title: 'Articles by ' ~ author.name,
12+
show_github: true,
1213
author_github: author.github,
1314
}) }}
1415
{% endblock %}
Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
1-
{% extends '@layout/default.html.twig' %}
2-
{% block json_ld %} {{ include('@jsonld/android/listen-for-android-install-referrer.jsonld.twig') }} {% endblock %}
1+
{% extends '@layout/blog-post.html.twig' %}
32

4-
{% block title %}Listen for Android install referrer{% endblock %}
5-
6-
{% block page_title %}
7-
{{ include('@partial/title-section.html.twig', {
8-
back_href: url('page::blog'),
9-
back_label: 'Back to Blog',
10-
badge: 'Android',
11-
article: article,
12-
}) }}
13-
{% endblock %}
14-
15-
{% block content %}
16-
<div class="wrap post-body-wrap">
17-
<div class="post-layout">
18-
19-
{{ include('@partial/left-menu.html.twig') }}
20-
21-
<article class="article">
22-
<div class="entry">
23-
{{ include('@partial/obsolete-warning.html.twig', {article: article}) }}
3+
{% block body %}
244
<h2>Getting Referrer Data at Install Time</h2>
255

266
<p class="mb-3">Have you ever wondered if Android market sends you information at the moment of app install? Wouldn't it be nice to create custom links to your Android application, including bits of information about the referrer, and send it directly to the app for processing at install? This could be a simple and accurate solution for mobile app install tracking, but I'm sure you can find this useful in many ways.</p>
@@ -43,11 +23,4 @@
4323
</div>
4424
</details>
4525
</div>
46-
</div>
47-
48-
{{ include('@partial/post-nav.html.twig') }}
49-
</article>
50-
51-
</div>
52-
</div>
5326
{% endblock %}
Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
1-
{% extends '@layout/default.html.twig' %}
2-
{% block json_ld %} {{ include('@jsonld/android/multiple-broadcast-receivers-in-the-same-app-for-the-same-action.jsonld.twig') }} {% endblock %}
1+
{% extends '@layout/blog-post.html.twig' %}
32

4-
{% block title %}Multiple broadcast receivers in the same app, for the same action{% endblock %}
5-
6-
{% block page_title %}
7-
{{ include('@partial/title-section.html.twig', {
8-
back_href: url('page::blog'),
9-
back_label: 'Back to Blog',
10-
badge: 'Android',
11-
article: article,
12-
}) }}
13-
{% endblock %}
14-
15-
{% block content %}
16-
<div class="wrap post-body-wrap">
17-
<div class="post-layout">
18-
19-
{{ include('@partial/left-menu.html.twig') }}
20-
21-
<article class="article">
22-
<div class="entry">
23-
{{ include('@partial/obsolete-warning.html.twig', {article: article}) }}
3+
{% block body %}
244
Did you come to a point where using multiple broadcast receivers to listen for the same intent, separatly, in the same android app, leads to unexpected results?
255
If that's the case, one broadcast receiver might consume the broadcasted intent, <a href="http://www.cillap.com/">online casino</a> leaving the others with nothing to receive.
266
This can be the case where you use 3rd party libraries with broadcast receivers defined.
@@ -43,11 +23,4 @@ The following is a solution for this kind of problem, a code snippet inspired by
4323
</div>
4424
</details>
4525
</div>
46-
</div>
47-
48-
{{ include('@partial/post-nav.html.twig') }}
49-
</article>
50-
51-
</div>
52-
</div>
5326
{% endblock %}

0 commit comments

Comments
 (0)